使用 WPF/MVVM 在运行时动态更改用户控件内容

本文关键字:用户 控件 动态 WPF MVVM 运行时 使用 | 更新日期: 2023-09-27 18:33:31

我尝试创建的屏幕是一个多部分结果查看器。批处理作业完成后,您将能够双击它并打开此屏幕,该屏幕将包含有关刚刚运行的批处理作业的基本数据的顶部部分(屏幕的顶部 30%,全宽(,然后较低的 70% 将包含一个左对齐的列表框(宽度的 20%(,其中包含一系列子结果和一个占据剩余 80% 宽度的详细信息窗格。

我希望它的行为方式是当您选择左侧列表框中的子结果时,右侧窗格将填充子结果的详细信息。因为它会很复杂并且需要可扩展,所以我想将每个子结果详细信息显示面板实现为 UserControl。

父 ViewModel 包含一个IDictionary<Enum.ResultType, IResultPanel> - 列表框将从此字典的键填充,当您选择一个选项时,它将从字典中获取 IResultPanel 对象,该对象将是用户控件,下面是一个示例代码段

public partial class SimpleCalcInfoResult : UserControl, IResultPanel
    {
        private SimpleCalcInfoResultViewModel _viewModel;
        public SimpleCalcInfoResult(SimpleCalcInfoResultViewModel viewModel)
        {
            InitializeComponent();
            _viewModel = viewModel;
        }
    }

IResultPanel 接口是一个空白的空接口,仅用于方便使用通用类型的上述字典,因为我觉得拥有用户控件字典太宽泛了。

遇到的问题是我无法弄清楚在父控件中使用什么 XAML 来拥有可更改的用户控制面板。显然你可以有

<local:MyControl> ... </local:MyControl>

作为硬编码的用户控件,但我如何拥有 XAML 的一部分,让我根据您选择的 ListBox 项更改显示的用户控件?

使用 WPF/MVVM 在运行时动态更改用户控件内容

这很容易通过 WPF 实现。但是,在使用 MVVM 时,我们会"操作"数据而不是 UI 控件。考虑到这一点,首先在Application.Resources部分中为每个自定义Panel控件声明一个DataTemplate

<DataTemplate DataType="{x:Type ViewModels:SimpleCalcInfoResultViewModel}">
    <Views:SimpleCalcInfoResult />
</DataTemplate>
...
<DataTemplate DataType="{x:Type ViewModels:MainViewModel}">
    <Views:MainView />
</DataTemplate>

现在您所要做的就是使用ContentControl在右下角的显示屏中显示相关的视图模型:

<ContentControl Content="{Binding ViewModel}" />

最后,将名为 ViewModelIResultPanel 类型的属性添加到父视图模型:

private IResultPanel viewModel = new FirstViewModel();
public IResultPanel ViewModel
{
    get { return viewModel; }
    set { if (viewModel != value) { viewModel = value; NotifyPropertyChanged("ViewModel"); } }
}

现在,要在应用程序中显示不同的Panel,您需要做的就是将此属性设置为不同的值:

ViewModel = new SimpleCalcInfoResultViewModel();