首页 > 解决方案 > WPF MVVM 在代码中绑定动态控件并传入View

问题描述

我正在使用 MVVM 开发 WPF 应用程序。我有两页。我在第 1 页中有多个用户控件,在从第 1 页选择用户控件时,我想在第 2 页中显示选定的用户控件。下面是我的代码。

视图模型代码

public RelayCommand<string> OnClickSelectWidgetCommand => new RelayCommand<string>((setUserControlName) =>
    {
        using (new CursorWait())
        {
            var MyContentControl = setUserControlName;
            MessageBox.Show(MyContentControl);

            //How to render UserControl to View?
        }

    }, true);

在上面的代码中,我在setUserControlName变量中获得了 UserControl 名称。现在如何将该 UserControl 绑定到 XAML 页面?以下是我尝试过的代码。

查看代码

<StackPanel Background="Black" VerticalAlignment="Top">
<Border Name="UserControl1BorderLow" BorderBrush="White" BorderThickness="0" >
    <ItemsControl ItemsSource="{Binding LowCollection}" Margin="4,0" >
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <WrapPanel HorizontalAlignment="Left" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <controls:UserControlColumn1XL HorizontalAlignment="Left" Margin="2" />
                <!--what can I do here in above line to make it dynamically render the userControl in place of UserControlColumn1XL-->
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Border></StackPanel>

上面的代码,在 DataTemplate 中需要改变什么来动态绑定 UserControls?

标签: c#wpfmvvmuser-controlsdatatemplate

解决方案


有两种方法可以解决这个问题,一种是根据您的数据类型(DataTemplates)设置模板,另一种是根据数据本身(DataTriggers)设置模板。

在第一种情况下,您的 LowCollection 应该是一个对象数组,或者您的视图模型都派生自某个基类(ViewModel1、ViewModel2 等)。在这种情况下,您可以完全摆脱您的 itemtemplate,只需添加 DataTemplates 以指定 ItemsControl 中的每个项目应如何表示:

<ItemsControl.Resources>

    <DataTemplate DataType="{x:Type local:ViewModel1}">
        <UserControl1 />
    </DataTemplate>

    <DataTemplate DataType="{x:Type local:ViewModel2}">
        <UserControl2 />
    </DataTemplate>

    ... etc...

在第二种情况下,您需要根据视图模型中某些属性的值设置模板。在这种情况下,您确实需要设置 ItemTemplate,并给它一个 Style,它使用数据触发器来设置适当的 DataTemplate:

    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <ContentPresenter Content="{Binding}">
                <ContentPresenter.Style>
                    <Style TargetType="{x:Type ContentPresenter}">
                        <Style.Triggers>
                            <DataTrigger Binding="{Binding YourProperty}" Value="YourValue1">
                                <Setter Property="ContentTemplate" Value="{StaticResource YourDataTemplate1}" />
                            </DataTrigger>
                            <DataTrigger Binding="{Binding YourProperty}" Value="YourValue2">
                                <Setter Property="ContentTemplate" Value="{StaticResource YourDataTemplate2}" />
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </ContentPresenter.Style>
            </ContentPresenter>
        </DataTemplate>
    </ItemsControl.ItemTemplate>

这里要注意的相关部分是视图模型中有一个名为的属性,YourProperty它可以有两个值,即YourValue1YourValue2; 上面的样式然后根据 的值选择YourDataTemplate1或。YourDataTemplate2YourProperty


推荐阅读