我正在尝试实现一组控件,这些控件将由应用程序中的各种仪器包装器/适配器使用。这些控件的目标是提供所有连接设备将使用的功能,例如验证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的另一个实例,而不是视图使用的实例吗?