C# 使用WPF/MVVM在运行时动态更改UserControl内容
我尝试创建的屏幕是一个多部分结果查看器。当批处理作业完成时,您将能够双击它并打开此屏幕,其中将包含关于刚刚运行的批处理作业的基本数据的顶部部分(屏幕顶部30%,全宽),然后下部70%将由左对齐的列表框组成(宽度的20%)选择子结果和占据剩余80%宽度的详细信息窗格 我希望它的行为方式是,当您在左侧列表框中选择子结果时,右侧窗格将填充子结果的详细信息。因为它将是复杂的并且需要可伸缩的,所以我想将每个子结果细节显示面板实现为一个UserControl 父视图模型包含一个C# 使用WPF/MVVM在运行时动态更改UserControl内容,c#,wpf,user-controls,C#,Wpf,User Controls,我尝试创建的屏幕是一个多部分结果查看器。当批处理作业完成时,您将能够双击它并打开此屏幕,其中将包含关于刚刚运行的批处理作业的基本数据的顶部部分(屏幕顶部30%,全宽),然后下部70%将由左对齐的列表框组成(宽度的20%)选择子结果和占据剩余80%宽度的详细信息窗格 我希望它的行为方式是,当您在左侧列表框中选择子结果时,右侧窗格将填充子结果的详细信息。因为它将是复杂的并且需要可伸缩的,所以我想将每个子结果细节显示面板实现为一个UserControl 父视图模型包含一个IDictionary,列表框
IDictionary
,列表框将从此字典的键填充,当您选择一个选项时,它将从字典中获取IResultPanel对象,该字典将是用户控件,下面是一个示例代码段
public partial class SimpleCalcInfoResult : UserControl, IResultPanel
{
private SimpleCalcInfoResultViewModel _viewModel;
public SimpleCalcInfoResult(SimpleCalcInfoResultViewModel viewModel)
{
InitializeComponent();
_viewModel = viewModel;
}
}
IResultPanel接口是一个空白的空接口,仅用于方便将上面的字典与公共类型结合起来,因为我觉得拥有UserControls的字典太广泛了
我遇到的问题是,我不知道在父控件中使用什么XAML来拥有一个可变的UserControl面板。显然你可以
<local:MyControl> ... </local:MyControl>
。。。
作为一个硬编码的用户控件,但是我如何拥有XAML的一部分,它将允许我根据您选择的列表框项目来更改显示的用户控件?这很容易用WPF实现。然而,当使用MVVM时,我们“操纵”数据而不是UI控件。记住这一点,首先在
应用程序中为每个自定义面板控件声明数据模板
<DataTemplate DataType="{x:Type ViewModels:SimpleCalcInfoResultViewModel}">
<Views:SimpleCalcInfoResult />
</DataTemplate>
...
<DataTemplate DataType="{x:Type ViewModels:MainViewModel}">
<Views:MainView />
</DataTemplate>
最后,将名为ViewModel
的IResultPanel
类型的属性添加到父视图模型:
private IResultPanel viewModel = new FirstViewModel();
public IResultPanel ViewModel
{
get { return viewModel; }
set { if (viewModel != value) { viewModel = value; NotifyPropertyChanged("ViewModel"); } }
}
现在,要在应用程序中显示不同的面板
,只需将此属性设置为不同的值:
ViewModel = new SimpleCalcInfoResultViewModel();
了解WPF模板,即DataTemplateSelectors()和DataTemplates(),以及DataTypeThank非常感谢,非常全面的回答。那么我的想法是否正确,我仍然创建并定义了一个UserControl xaml类,比如SimpleCalcInfoResult,其中包含该结果类型的所有显示逻辑,并且在数据模板中只指定一行,即该UserControl的实例创建?还有一个问题,我的SimpleCalcinoResult用户控件有一个构造函数,它接受一个参数,即SimpleCalcinoResultViewModel对象。如何编写上面的datatemplate来创建用户控件,并将视图模型对象作为第一个参数传递给构造函数?对您的第一个注释是。。。这就是你需要做的。定义了这些DataTemplate
s后,无论框架在哪里看到视图模型的实例,它都会显示指定的UserControl
。你的第二个评论似乎有点困惑。。。您的构造函数将视图模型作为参数,但是使用此方法,您不需要这样做。。。DataTemplate
代替设置DataContext
。通过将视图模型的DataContext
转换为正确类型的视图模型,您仍然可以从UserControl
代码隐藏访问视图模型:ThisViewModel vm=(ThisViewModel)DataContext代码>您好,很抱歉响应延迟。在第2部分中,我尝试了您所说的,但是在SimpleCalcInfoResult视图的构造函数中,我尝试按照您所说的将DataContext强制转换为VM类型,但是视图的DataContext为null。我是否错过了一个关键步骤?在调用构造函数时,它可能还没有设置好。尝试使用窗口。加载事件并将代码放入该处理程序中。
ViewModel = new SimpleCalcInfoResultViewModel();