将 ViewModel 定义为用于数据绑定的 DependencyProperty 是一种不好的做法吗?
Is it a bad practice to define a ViewModel as a DependencyProperty for data-binding?
我有一个 UserControl MyView,它有一个内部 UserControl SubView。
2个UserControls的视图模型与视图具有相同的层次结构,
即,MyViewModel 内部有 SubViewModel,如下面的代码所示。
public class MyViewModel
{
private readonly SubViewModel _subViewModel = new SubViewModel();
public SubViewModel SubViewModel { get { return _subViewModel; } }
private void HandleSubViewModel()
{
// Do what is necessary to handle SubViewModel
}
}
我的问题是如何将 SubViewModel 绑定到 SubView。
现在我在 SubView 的代码隐藏中定义 SubViewModel 并将其绑定到 MyViewModel class 的 SubViewModel 属性。
public partial class SubView : UserControl
{
public static readonly DependencyProperty SubViewModelProperty = DependencyProperty.Register(
"SubViewModel", typeof (SubViewModel), typeof (SubView), new PropertyMetadata(default(SubViewModel)));
public SubViewModel SubViewModel
{
get { return (SubViewModel) GetValue(SubViewModelProperty); }
set { SetValue(SubViewModelProperty, value); }
}
}
<UserControl x:Class="MyProject.View.MyView"
xmlns:parts="clr-namespace:MyProject.View.Parts">
<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=MyViewModel}">
<parts:SubView SubViewModel="{Binding SubViewModel}"/>
</Grid>
</UserControl>
以这种方式绑定内部视图模型是一种不好的做法吗?
如果可以,如何绑定比较好?
它可能不好的一个原因是,如果 SubViewModel
中的 属性 发生变化,MyViewModel
将无法知道。所以例如如果您需要在 MyViewModel
级别执行和处理任何验证,您将无法执行此操作。
要解决这个问题,当 属性 发生变化时;您必须在 SubViewModel
中引发一个事件并让 MyViewModel
订阅它并在收到它后做出适当的反应。
除此之外,我认为没有任何缺点。但是请阅读这些链接以获取更多信息:
MVVM and nested view models
MVVM: How to handle interaction between nested ViewModels?
你可以这样做:
查看型号:
public class MyViewModel
{
private readonly SubViewModel _subViewModel;
public SubViewModel SubViewModel
{
get { return _subViewModel; }
}
public MyViewModel()
{
_subViewModel = new SubViewModel();
_subViewModel.Text1 = "blabla";
}
}
public class SubViewModel : DependencyObject
{
public string Text1
{
get { return (string)GetValue(Text1Property); }
set { SetValue(Text1Property, value); }
}
public static readonly DependencyProperty Text1Property =
DependencyProperty.Register("Text1", typeof(string), typeof(SubViewModel));
}
子用户控件:
<UserControl x:Class="WpfApplication1.SubUserControl"
xmlns= ... >
<Grid Height="200" Width="300" Background="Aqua">
<TextBlock Text="{Binding SubViewModel.Text1}" />
</Grid>
我有一个 UserControl MyView,它有一个内部 UserControl SubView。
2个UserControls的视图模型与视图具有相同的层次结构, 即,MyViewModel 内部有 SubViewModel,如下面的代码所示。
public class MyViewModel
{
private readonly SubViewModel _subViewModel = new SubViewModel();
public SubViewModel SubViewModel { get { return _subViewModel; } }
private void HandleSubViewModel()
{
// Do what is necessary to handle SubViewModel
}
}
我的问题是如何将 SubViewModel 绑定到 SubView。
现在我在 SubView 的代码隐藏中定义 SubViewModel 并将其绑定到 MyViewModel class 的 SubViewModel 属性。
public partial class SubView : UserControl
{
public static readonly DependencyProperty SubViewModelProperty = DependencyProperty.Register(
"SubViewModel", typeof (SubViewModel), typeof (SubView), new PropertyMetadata(default(SubViewModel)));
public SubViewModel SubViewModel
{
get { return (SubViewModel) GetValue(SubViewModelProperty); }
set { SetValue(SubViewModelProperty, value); }
}
}
<UserControl x:Class="MyProject.View.MyView"
xmlns:parts="clr-namespace:MyProject.View.Parts">
<Grid DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}, Path=MyViewModel}">
<parts:SubView SubViewModel="{Binding SubViewModel}"/>
</Grid>
</UserControl>
以这种方式绑定内部视图模型是一种不好的做法吗?
如果可以,如何绑定比较好?
它可能不好的一个原因是,如果 SubViewModel
中的 属性 发生变化,MyViewModel
将无法知道。所以例如如果您需要在 MyViewModel
级别执行和处理任何验证,您将无法执行此操作。
要解决这个问题,当 属性 发生变化时;您必须在 SubViewModel
中引发一个事件并让 MyViewModel
订阅它并在收到它后做出适当的反应。
除此之外,我认为没有任何缺点。但是请阅读这些链接以获取更多信息: MVVM and nested view models
MVVM: How to handle interaction between nested ViewModels?
你可以这样做: 查看型号:
public class MyViewModel
{
private readonly SubViewModel _subViewModel;
public SubViewModel SubViewModel
{
get { return _subViewModel; }
}
public MyViewModel()
{
_subViewModel = new SubViewModel();
_subViewModel.Text1 = "blabla";
}
}
public class SubViewModel : DependencyObject
{
public string Text1
{
get { return (string)GetValue(Text1Property); }
set { SetValue(Text1Property, value); }
}
public static readonly DependencyProperty Text1Property =
DependencyProperty.Register("Text1", typeof(string), typeof(SubViewModel));
}
子用户控件:
<UserControl x:Class="WpfApplication1.SubUserControl"
xmlns= ... >
<Grid Height="200" Width="300" Background="Aqua">
<TextBlock Text="{Binding SubViewModel.Text1}" />
</Grid>