简体   繁体   English

WPF和MVVM:动态将UserControl绑定到XAML

[英]WPF and MVVM: bind UserControl to XAML dynamically

seems like a trivial task: i am building a wpf application, using MVVM pattern. 似乎是一项琐碎的任务:我正在使用MVVM模式构建wpf应用程序。 what i want is dynamically change part of a view, using different UserControls, dependent on user input. 我想要的是根据用户输入,使用不同的UserControls动态更改视图的一部分。

let's say, i have got 2 UserControls, one with a button, and another with a label. 假设我有2个UserControl,一个带有按钮,另一个带有标签。 in main view i have a container for that. 在主视图中,我为此提供了一个容器。 following XAML "works": 以下XAML“有效”:

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

and a UserControl element with buttons pops up. 弹出带有按钮的UserControl元素。 if i change it to another one, it works too. 如果我将其更改为另一种,它也可以使用。 question is how to feed that groupbox dynamically. 问题是如何动态地添加该组框。 if i put something like that in my model view: 如果我在模型视图中放入类似内容:

private UserControl _myControl;
public UserControl MyControl
{
    get
    {
        return _myControl;
    }
    set
    {
        _myControl= value;
        InvokePropertyChanged("MyControl");
    }
}

and change my view XAML to something like: 并将我的视图XAML更改为:

<GroupBox Header="container" >
    <ItemsControl ItemsSource="{Binding MyControl}" />
</GroupBox>

and feed it from command with usercontrol for button or for label: nothing happens, although "MyControl" variable is set and is "invoke property changed".. 并使用usercontrol从命令中为按钮或标签提供命令:尽管设置了“ MyControl”变量并且“调用属性已更改”,但是什么也没发生。

Obviously there are many ways to skin this particular cat - but to answer the question of why it doesn't work you need to look into the ItemsSource property of ItemsControl on MSDN . 显然,有很多方法可以使这种特殊的猫皮肤化-但是要回答为什么它不起作用的问题,您需要查看MSDN上ItemsControl的ItemsSource属性。

The items control is designed to show multiple items, provided through an IEnumerable passed to the ItemsSource property. 项目控件旨在显示多个项目,这些项目是通过传递给ItemsSource属性的IEnumerable提供的。 You are passing a UserControl, so the binding will fail. 您正在传递UserControl,因此绑定将失败。

For your example, I would change the ItemsControl to a ContentControl and bind the content to your MyControl property. 对于您的示例,我将ItemsControl更改为ContentControl并将内容绑定到MyControl属性。 This should then work. 然后,这应该工作。

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

However, I would strongly recommend looking into other ways of doing this - having a control in your VM breaks MVVM to my mind. 但是,我强烈建议您寻找其他方法来执行此操作-在您的VM中进行控制会使我无法想到MVVM。 Depending on what you are doing look at data templates - @Sheridan's link in the comments provides an great description of a way to do it. 根据您正在执行的操作,查看数据模板-注释中的@Sheridan链接提供了一种很好的方法说明。

Couldn't post this as a comment so adding as answer.. 无法将此内容发布为评论,因此添加为答案..

Have a look at this: Implementing an own "Factory" for reusing Views in WPF 看一下这一点: 实现自己的“工厂”以在WPF中重用视图

It uses DataTemplates but doesn't require the DataTemplate section for each view. 它使用DataTemplates,但不需要每个视图的DataTemplate部分。 If you potentially have a lot of user controls/views you wish to display or you are reusing through multiple views or you are intending to actually dynamically generate a view (versus just loading an existing user control) then this might suite your needs. 如果您可能希望显示很多用户控件/视图,或者正在多个视图中重用,或者打算实际动态生成视图(而不是仅加载现有的用户控件),那么这可能适合您的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM