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



背景:

我有一个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模式,所以我不想在用户控件(视图)中公开要从主窗口设置的属性。

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

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

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

如果在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. 手动将其添加到父Grid元素的Children数组中

显然这不是我的建议。除了复杂性之外,使用前一种方法,您还可以很好地使用VisualStudio设计器。

最新更新