以MVVM模式将数据传递给用户控件

时间:2012-03-22 04:35:22

标签: wpf mvvm user-controls

背景:

我有一个WPF应用程序,其主窗口包含用户控件。我想将一个值从主窗口传递给用户控件。

在主窗口的构造函数中,我有代码:

    public MainWindow()
    {
        InitializeComponent();
        _vm = new MainWindowViewModel();
        this.DataContext = _vm;
        ucControl = new UserControl1("NameSet");
    }

(ucControl是我的用户控件)

用户控件有两个构造函数:

    public UserControl1()
    {
        InitializeComponent();
        this.ID = ID.GetNewID;
    }

    public UserControl1(string name)
    {
        InitializeComponent();
        _vm = new UCViewModel(name);
        this.DataContext = _vm;
        this.ID = ID.GetNewID;
    }

问题是:虽然调用了第二个构造函数(带参数),但它没有加载到主窗口中。我在用户控件的加载事件中检查了ID(this.ID),我在默认构造函数中看到了ID集,并且其DataContext为null。由于这个原因,我的用户控件中没有“name”字符串。

请帮忙吗?由于我使用的是MVVM模式,因此我不希望在主窗口中为用户控件(视图)公开属性。

1 个答案:

答案 0 :(得分:1)

您正在实例化UserControl1对象两次:

  1. 一旦进入XAML。 < uc:UserControl1> element使用默认构造函数实例化UserControl1对象,并将其分配给成员ucControl。

  2. 您在MainWindow对象的构造函数中再次实例化它

  3. 如果你在UserControl的构造函数中放置一个断点,你会发现它被调用了两次。我假设WPF在分配动态UserControl(上面的#2)之后实例化并初始化XAML的UserControl(上面的#1),这就是你在MainWindow的逻辑树中看到前者的原因。

    您应该只有一个实例。如果你想参数化一个用户控件,你提到的规范范式是你不想做的(为什么??)。如果您有这样的属性,可以在XAML中设置它:< uc:UserControl1 x:Name =“...”YourProperty =“NameSet>

    在UserControl中公开这样的属性是一行:

    public YourProperty { get; set; }
    

    如果您坚持不使用此行,则应执行以下操作:

    1. 删除XAML的用户控件。
    2. 在主窗口中,订阅Loaded事件
    3. 在Loaded事件的处理程序中,实例化一个新的UserControl1 - 使用您想要的任何构造函数参数。
    4. 手动将其添加到父网格元素的Children数组
    5. 显然这不是我的建议。除了复杂性之外,使用前一种方法,您还可以很好地使用Visual Studio设计器。