WPF/MVVM在运行时加载UserControl

use*_*575 5 c# wpf mvvm

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

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

StartView app = new StartView();
StartViewModel context = new StartViewModel();
Run Code Online (Sandbox Code Playgroud)

StartView

<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>
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

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>
Run Code Online (Sandbox Code Playgroud)

UCStatistikViewModel

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

        public UCStastistikViewModel()
        {
        }

        #region Properties / Commands
        #endregion

        #region Methods
        #endregion
    }
}
Run Code Online (Sandbox Code Playgroud)

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

再见j

Rac*_*hel 18

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

例如,

<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>
Run Code Online (Sandbox Code Playgroud)

另外,摆脱<UserControl.DataContext>你的UserControl.本DataContext应由无论是使用控制,在用户控件没有定义传递的:)

编辑

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

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