首页 > 解决方案 > WPF ContentPresenter 不适用于 ResourceDictionary 中的单个条目

问题描述

我的 ContentPresenter 有一个奇怪的问题。在我的标准 WPF 应用程序中,我有一个“TestView”、一个“TestViewModel”、一个“MainWindowView”和一个“MainWindowViewModel”。MainWindowView 包含一个 ContentPresenter,其内容绑定到 MainWindowViewModel 的 ViewModelProperty:

<ContentPresenter DockPanel.Dock="Right"
                  Height="Auto"
                  Width="Auto"
                  Content="{Binding CurrentContentViewModel}" />

和视图模型:

private IViewModel _currentContentViewModel;
public IViewModel CurrentContentViewModel
{
    get
    {
        return  _currentContentViewModel;
    }
    set
    {
        _currentContentViewModel = value;
        OnPropertyChanged();
    }
 }

TestView 绑定到我的 App.xaml 中的 TestViewModel:

<Application.Resources>
    <ResourceDictionary >
        <DataTemplate DataType="{x:Type viewModel:TestViewModel}">
            <view:TestView />
        </DataTemplate>
    </ResourceDictionary>
</Application.Resources>

当我现在将 TestViewModel 的实例分配给 CurrentContentViewModel 时,ContentPresenter 会显示 TestViewModel 的类名:

MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
MainWindowView mainWindowView = new MainWindowView(mainWindowViewModel);

TestViewModel testViewModel = new TestViewModel();

mainWindowView.Show();
mainWindowViewModel.CurrentContentViewModel = testViewModel;

我是如何解决问题的?我在 ResourceDictionary 中添加了一个空样式标签、一个 SolidColorBrush 定义或其他内容:

<Application.Resources>
    <ResourceDictionary >
        <DataTemplate DataType="{x:Type viewModel:TestViewModel}">
            <view:TestView />
        </DataTemplate>

        <SolidColorBrush x:Key="ColorBrushDummy" Color="HotPink"/>

    </ResourceDictionary>
 </Application.Resources>

现在一切正常,ContentPresenter 显示 TestView。

现在我的问题是:为什么?

编辑:

我制作了一个新的 SampleProject 并重现了该错误。当我开始使用 App.xaml.cs 的 OnStartup 方法时,就会出现问题:

protected override void OnStartup(StartupEventArgs e)
{
    base.OnStartup(e);

    MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
    MainWindowView mainWindowView = new MainWindowView(mainWindowViewModel);

    TestViewModel testViewModel = new TestViewModel();

    mainWindowView.Show();
    mainWindowViewModel.CurrentContentViewModel = testViewModel;
}

我的测试视图:

<UserControl x:Class="ErrorSample.TestView"
         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:local="clr-namespace:ErrorSample"
         mc:Ignorable="d" 
         d:DesignHeight="450"
         d:DesignWidth="800"
         d:DataContext="{d:DesignInstance local:TestViewModel}">
<Grid Background="Red">
        <TextBlock Text="{Binding Text}"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"/>
</Grid>

我的测试视图模型:

public class TestViewModel : ViewModelBase
{
    public string Text { get; } = "Sample Text";
}

还有我的 MainWindowViewModel:

public class MainWindowViewModel : ViewModelBase
{
    private IViewModel _currentContentViewModel;

    public IViewModel CurrentContentViewModel
    {
        get => _currentContentViewModel;
        set
        {
            _currentContentViewModel = value;
            OnPropertyChanged();
        }
    }

    public MainWindowViewModel()
    {

    }
}

标签: c#wpfmvvmresourcedictionarycontentpresenter

解决方案


推荐阅读