使用 WPF/MVVM 在运行时动态更改 UserControl 内容 [英] Dynamically changing UserControl content at run time with WPF/MVVM

查看:78
本文介绍了使用 WPF/MVVM 在运行时动态更改 UserControl 内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

The screen I am trying to create is a multi-part results viewer. When your batch job completes, you will be able to double click on it and open this screen, which will contain a top section of basic data about the batch job that just ran (top 30% of screen, full width), then the lower 70% will consist of a left aligned listbox (20% of the width) with a selection of Sub-Results and a Detail pane taking up the remaining 80% of the width.

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

The way I want it to behave is when you select the Sub Result on the left listbox, the right hand pane will populate with the details of the sub result. Because it is going to be complex and needs to be scalable, I would like to implement each sub result detail display panel as a UserControl.

父 ViewModel 包含一个 IDictionary - 列表框将从此字典的键填充,当您选择一个选项时,它将获取 IResultPanel 对象来自将是用户控件的字典,下面是一个示例片段

The parent ViewModel contains an IDictionary<Enum.ResultType, IResultPanel> - and the listbox will be populated from the keys of this dictionary, and when you select an option, it will fetch the IResultPanel object from the dictionary which will be User Control, one example snippet below

public partial class SimpleCalcInfoResult : UserControl, IResultPanel
    {
        private SimpleCalcInfoResultViewModel _viewModel;

        public SimpleCalcInfoResult(SimpleCalcInfoResultViewModel viewModel)
        {
            InitializeComponent();
            _viewModel = viewModel;
        }
    }

IResultPanel 接口是一个空白的空接口,只是为了方便上面的 Dictionary 有一个通用类型,因为我觉得有一个 UserControls 的字典太宽泛了.

The IResultPanel interface is a blank empty interface, used only to facilitate being able to have the Dictionary above with a common type as I felt having a dictionary of UserControls was too broad.

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

The problem I've got is I can't figure out what XAML to use in the parent control to have a changeable UserControl panel. Obviously you can have

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

作为硬编码的用户控件,但我如何才能拥有一段 XAML 来让我更改显示的用户控件,具体取决于您选择的 ListBox 项目?

As a hard coded user control, but how can I have a section of XAML that will let me change which User Control is displayed, depending on which ListBox item you select?

推荐答案

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

This is simple to achieve with WPF. However, when using MVVM, we 'manipulate' data rather than UI controls. With that in mind, first declare a DataTemplate for each of your custom Panel controls in the Application.Resources section:

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

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

Now all you have to do is display the relating view model in your lower right display using a ContentControl:

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

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

Finally, add a property of type IResultPanel named ViewModel to your parent view model:

private IResultPanel viewModel = new FirstViewModel();

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

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

Now all you need to do to display a different Panel in your application is to set this property to a different value:

ViewModel = new SimpleCalcInfoResultViewModel();

这篇关于使用 WPF/MVVM 在运行时动态更改 UserControl 内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆