我正在尝试实现一组控件,这些控件将由应用程序中的各种仪器包装器/适配器使用 . 这些控件的目标是提供所有连接设备将使用的功能,例如验证IP地址,而不是让每个开发人员在添加新设备支持时编写自己的IP地址 . 我们也在考虑转向WPF和MVVM作为重新分解的一部分 . 我正在努力理解的问题是来自主窗口的vm如何与控件的vm共享数据(在此示例中为经过验证的IP地址) . 验证IP地址后的控制vm是否将其写回模型,主表单vm从那里获取它?或者是否有来自控件vm的依赖属性将字符串推入主窗体VM?

用户控件的XAML这将绑定到控件的vm

<Label Content="IP Address" HorizontalAlignment="Left" VerticalAlignment="Top" Width="78"/>
    <TextBox Text="{Binding Path=Part1, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="44" RenderTransformOrigin="4.427,0.626" HorizontalContentAlignment="Center"/>
    <TextBox Text="{Binding Path=Part2, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="44" RenderTransformOrigin="4.427,0.626" HorizontalContentAlignment="Center"/>
    <TextBox Text="{Binding Path=Part3, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="44" RenderTransformOrigin="4.427,0.626" HorizontalContentAlignment="Center"/>
    <TextBox Text="{Binding Path=Part4, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Center" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="44" RenderTransformOrigin="4.427,0.626" HorizontalContentAlignment="Center"/>
    <Button Command="{Binding ValidateCommand}" Content="Validate" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" />
    <TextBox Text="{Binding Result}" TextWrapping="Wrap" Width="179" Margin="0,0,0,63.6"/>

vm具有以下属性

public string Part1 { get; set; }
    public string Part2 { get; set; }
    public string Part3 { get; set; }
    public string Part4 { get; set; }
    private StringBuilder result = new StringBuilder();
    public string IPAddress { get; set; }

    public string Result
    {
        get { return (string)GetValue(ResultProperty); }
        set { SetValue(ResultProperty, value); }
    }

    public static readonly DependencyProperty ResultProperty =
        DependencyProperty.Register("Result", typeof(string), typeof(IPAddressViewModel), new UIPropertyMetadata(""));

和用户控件按钮的命令类

private readonly IPAddressViewModel _vm;
    public IPAddressValidate(IPAddressViewModel vm)
    {
        _vm = vm;
    }

    public bool CanExecute(object parameter)
    {
        // ...... 
    }

    public event EventHandler CanExecuteChanged
    {
        // ...... 
    }

    public void Execute(object parameter)
    {
        _vm.Validates();
    }

控件按预期工作,并在输入数据后启用验证按钮,然后在按钮单击时验证它 . 到现在为止还挺好 .

然后我尝试以这样的形式使用此控件

<Button Command="{Binding ConnectCommand}" Content="Connect" HorizontalAlignment="Left" Margin="10,151,0,0" VerticalAlignment="Top" Width="75" Height="22"/>
    <TextBox Text="{Binding Result}" HorizontalAlignment="Left" Height="23" Margin="124,151,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="384"/>
    <Controls:IPAddress HorizontalAlignment="Left" Margin="10,85,0,0" VerticalAlignment="Top" Height="26" Width="498"/>

然后,我实现了处理连接按钮的命令,这就是它完全崩溃的地方,因为我看不到从用户控件获取经过验证的字符串的方法 . 该值是控件vm的公共属性,但主窗口vm如何获取它的实例需要注入?这是错误的做法还是我错过了一步?

谢谢你的回答Sheridan非常感谢用户控件我在构造函数中创建了它的vm,而不是在主窗口的vm中,不像这个例子不正确吗?

用户控制代码背后

public partial class IPAddress : UserControl
{
    private IPAddressViewModel _vm;

    public IPAddress()
    {
        InitializeComponent();

        //Create an insatnce of the view model and set it as the data context for this form
        _vm = new IPAddressViewModel();
        this.DataContext = _vm;
    }
}

主要表格代码背后

public partial class MainWindow : Window
{
    private AdapterViewModel _vm;

    public MainWindow()
    {
        InitializeComponent();

        //Create an insatnce of the view model and set it as the data context for this form
        _vm = new AdapterViewModel();
        this.DataContext = _vm;
    }
}

我不知道如何从你的例子中实现

ParameterViewModel viewModel = new ParameterViewModel();
viewModel.OnParameterChange += ParameterViewModel_OnParameterChange;

这不会创建用户控件vm的另一个实例,而不是视图使用的实例吗?