WPF/MVVM 在运行时加载用户控件 [英] WPF/MVVM Load an UserControl at Runtime

查看:125
本文介绍了WPF/MVVM 在运行时加载用户控件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有很多关于我的问题的文章,但我找不到解决方案.我是 WPF - MVVM 的新手,我试图了解 MVVM-Logic.所以我做了一个小项目来理解这一点.对于我以后的应用程序,我想将 UserControls 动态加载到我的 Window.

i know that there a many articles about my problem but i cant find a solution. I am new in WPF - MVVM and i try to understand the MVVM-Logic. So i made a little project to understand that. For my later apps i want to load UserControls dynamicly to my Window.

在我的 StartView 中,我有一个到 StartViewModel 的绑定.(绑定在APP.xaml中)

In my StartView i have a Binding to the StartViewModel. (The Binding is in the APP.xaml)

StartView app = new StartView();
StartViewModel context = new StartViewModel();

开始视图

<Window x:Class="test.Views.StartView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:views="clr-namespace:test.ViewModel"
        Title="Window1" Height="300" Width="516">
    <Grid>
        <Menu IsMainMenu="True" Margin="0,0,404,239">
            <MenuItem Header="_Einstellungen">
                <MenuItem Header="Server" />
            </MenuItem>
        </Menu>
        <ContentControl Content="{Binding LoadedControl}" Margin="0,28,0,128" />
    </Grid>
</Window>

StartViewModel

the StartViewModel

namespace test.ViewModel
{
    public class StartViewModel : ViewModelBase
    {
        #region Fields
        private UCStastistikViewModel _loadedControl;
        #endregion

        public StartViewModel()
        {
            LoadedControl = new UCStastistikViewModel();
        }

        #region Properties / Commands
        public UCStastistikViewModel LoadedControl
        {
            get { return _loadedControl; }
            set
            {
                if (value == _loadedControl)
                    return;

                _loadedControl = value;
                OnPropertyChanged("LoadedControl");
            }
        }
        #endregion

        #region Methods

        #endregion
    }
}

UCStatistikView

UCStatistikView

<UserControl x:Class="test.Views.UCStatistik"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:vm="clr-namespace:test.ViewModel"
             mc:Ignorable="d" 
             d:DesignHeight="188" d:DesignWidth="508">
    <UserControl.DataContext>
        <vm:UCStastistikViewModel />
    </UserControl.DataContext>
    <Grid Background="red">       
    </Grid>
</UserControl>

UCStatistikViewModel

UCStatistikViewModel

namespace test.ViewModel
{
    public class UCStastistikViewModel : ViewModelBase
    {
        #region Fields
        #endregion

        public UCStastistikViewModel()
        {
        }

        #region Properties / Commands
        #endregion

        #region Methods
        #endregion
    }
}

现在我想在 StartView 的 ContentControl 中加载我的 UCStatistikView.但是在 Startview 中只显示了 Path test.UCStatistikViewModel 而不是整个 UC任何人都可以给我一些想法我的问题在哪里/我哪里出错了?

Now i want to load my UCStatistikView in the ContentControl of my StartView. But in the Startview only the Path test.UCStatistikViewModel is shown instead of the whole UC Can anybody give me some Ideas where my problem is / where im am going wrong ?

再见 j

推荐答案

您的 ViewModel 不应该关心 UserControl.相反,让它们持有 ViewModel,并让 WPF 解决如何使用 DataTemplate 绘制 ViewModel.

Your ViewModels should not care about UserControls. Instead, have them hold ViewModels, and let WPF resolve how to draw the ViewModel with a DataTemplate.

例如

<Window x:Class="test.Views.StartView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:views="clr-namespace:test.Views"
        xmlns:viewmodels="clr-namespace:test.ViewModel"
        Title="Window1" Height="300" Width="516">

    <Window.Resources>
        <DataTemplate DataType="{x:Type viewmodels:UCStastistikViewModel}">
            <views:UCStastistikView />
        </DataTemplate>
    </Window.Resources>

    <Grid>
        <Menu IsMainMenu="True" Margin="0,0,404,239">
            <MenuItem Header="_Einstellungen">
                <MenuItem Header="Server" />
            </MenuItem>
        </Menu>
        <ContentControl Content="{Binding LoadedControl}" Margin="0,28,0,128" />
    </Grid>
</Window>

另外,去掉 UserControl 中的 .DataContext 应该由使用控件的任何对象传入,而不是在 UserControl 中定义 :)

Also, get rid of the <UserControl.DataContext> in your UserControl. The DataContext should be passed in by whatever is using the control, not defined in the UserControl :)

编辑

根据您对之前关于通过切换 ViewModel 切换出 StartPage 内容的回答的评论,您可能有兴趣查看 我的这篇文章.它的标题是Navigation with MVVM,但是同样的概念也适用于切换视图或用户控件

Based on your comment to an earlier answer about switching out the content of the StartPage by switching a ViewModel, you may be interested in looking at this post of mine. It's titled Navigation with MVVM, however the same concept applies for switching Views or UserControls

基本上,您将创建 ViewModelBase 类型的属性 LoadedControl 而不是对其类型进行硬编码,然后将其设置为您想要在 ContentControl 中显示的任何对象.WPF 的 DataTemplates 将负责为 ViewModel 连接正确的视图.

Basically, you'd make the property LoadedControl of type ViewModelBase instead of hard-coding it's type, and then set it to whatever object you want displayed in your ContentControl. WPF's DataTemplates will take care of hooking up the correct View for the ViewModel.

这篇关于WPF/MVVM 在运行时加载用户控件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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