WPF和MVVM:动态绑定UserControl到XAML

本文关键字:UserControl XAML 动态绑定 MVVM WPF | 更新日期: 2023-09-27 18:10:19

似乎是一个微不足道的任务:我正在构建一个wpf应用程序,使用MVVM模式。我想要的是动态地改变视图的一部分,使用不同的UserControls,依赖于用户输入。

让我们说,我有2个用户控件,一个带有按钮,另一个带有标签。在主视图中,我有一个容器。以下XAML "works":

<GroupBox Header="container" >
    <local:UserControlButton />
</GroupBox>

和一个带有按钮的UserControl元素弹出。如果我把它换成另一个,它也能工作。问题是如何动态地为这个组框提供信息。如果我在模型视图中输入这样的东西:

private UserControl _myControl;
public UserControl MyControl
{
    get
    {
        return _myControl;
    }
    set
    {
        _myControl= value;
        InvokePropertyChanged("MyControl");
    }
}
并将我的视图XAML更改为:
<GroupBox Header="container" >
    <ItemsControl ItemsSource="{Binding MyControl}" />
</GroupBox>

并从命令中输入usercontrol for button或for label:没有任何变化,尽管"MyControl"变量被设置并且是"invoke property changed".

WPF和MVVM:动态绑定UserControl到XAML

显然,有很多方法可以为这个特定的猫添加皮肤,但是要回答为什么它不起作用的问题,您需要查看MSDN上ItemsControl的ItemsSource属性。

items控件被设计为显示多个项目,通过传递给ItemsSource属性的IEnumerable提供。你正在传递一个UserControl,所以绑定会失败。

对于您的示例,我会将ItemsControl更改为ContentControl,并将内容绑定到您的MyControl属性。这应该可以工作。

<GroupBox Header="container" >
    <ContentControl Content="{Binding MyControl}" />
</GroupBox>

然而,我强烈建议寻找其他方法来做到这一点-在你的VM中有一个控制打破MVVM在我看来。根据你所做的事情,看看数据模板——@Sheridan在评论中的链接提供了一个很好的方法描述。

不能作为评论发布,所以添加了一个答案…

看看这个:实现自己的"工厂"用于在WPF中重用视图

它使用DataTemplate,但不需要每个视图的DataTemplate部分。如果你可能有很多用户控件/视图,你希望显示或你是通过多个视图重用或你打算实际动态生成一个视图(而不是只是加载一个现有的用户控件),那么这可能满足您的需求。