如何在ViewModel中区分相似的UserControls

本文关键字:相似 UserControls 中区 ViewModel | 更新日期: 2023-09-27 18:14:36

WP8应用程序。我有xaml页面与4相同的UserControls。现在看起来很简单:

<TextBlock Text="name" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    <CheckBox Content="chk1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="0,0,0,0"/>
    <CheckBox Content="chk2" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="119,0,0,0"/>

我想将这些数据存储在对象集合中。现在我尝试使用DataContext和iccommand接口。这是愚蠢的使12个属性为每一个单一的控件,所以问题是我如何发送到DataContext信息关于哪一个UserControl正在操作现在?它会更容易使用,例如UserControls的索引或其他东西。

我正在学习mvvm…任何建议吗?

如何在ViewModel中区分相似的UserControls

有两种方法:数据-上下文继承或依赖属性。

第一种方法是利用子控件继承父控件的DataContext这一事实。假设你有一个主视图模型和子视图模型。然后,您可以简单地将每个UserControl绑定到适当的视图模型。如
<local:MyUserControl DataContext="{Binding FirstSubViewModel}" />
<local:MyUserControl DataContext="{Binding SecondSubViewModel}" />

你的用户控件将假设它的DataContext具有它需要的所有ICommand属性。


第二种方法是让您的用户控件定义类型为ICommand的依赖属性:
public static readonly DependencyProperty Command1Property = 
    DependencyProperty.Register(
    "Command1", typeof(ICommand),
    typeof(MyUserControl), null
    );
public ICommand Command1
{
    get { return (ICommand)GetValue(Command1Property); }
    set { SetValue(Command1Property, value); }
}

这样,控件的使用者将能够使用任何绑定方法绑定命令。如:

<local:MyUserControl Command1="{Binding chk1Command}" />
<local:MyUserControl Command1="{Binding ElementName=someControl,Path=SomeCommand}" />

这里唯一的技巧是你必须以某种方式绑定到用户控件中的依赖属性——这在Silverlight中很棘手,因为没有RelativeSource=FindAncestor绑定。一种方法是将LayoutRoot的DataContext设置为控件本身。如果你的makrup是这样的:

<UserControl ...>
    <Grid x:Name="LayoutRoot">
        <TextBlock Text="name" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        <CheckBox Content="chk1" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="0,0,0,0"/>
        <CheckBox Content="chk2" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="119,0,0,0"/>
    </Grid>
</UserControl>

那么在构造函数中,你将有:

public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();
        LayoutRoot.DataContext = this;
    }
}