Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ionic-framework/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用WPF/MVVM在运行时动态更改UserControl内容_C#_Wpf_User Controls - Fatal编程技术网

C# 使用WPF/MVVM在运行时动态更改UserControl内容

C# 使用WPF/MVVM在运行时动态更改UserControl内容,c#,wpf,user-controls,C#,Wpf,User Controls,我尝试创建的屏幕是一个多部分结果查看器。当批处理作业完成时,您将能够双击它并打开此屏幕,其中将包含关于刚刚运行的批处理作业的基本数据的顶部部分(屏幕顶部30%,全宽),然后下部70%将由左对齐的列表框组成(宽度的20%)选择子结果和占据剩余80%宽度的详细信息窗格 我希望它的行为方式是,当您在左侧列表框中选择子结果时,右侧窗格将填充子结果的详细信息。因为它将是复杂的并且需要可伸缩的,所以我想将每个子结果细节显示面板实现为一个UserControl 父视图模型包含一个IDictionary,列表框

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

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

父视图模型包含一个
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();