使用 ContentControl 在 WPF 中显示视图不起作用

Posted

技术标签:

【中文标题】使用 ContentControl 在 WPF 中显示视图不起作用【英文标题】:Using ContentControl to display views in WPF doesn't work 【发布时间】:2015-02-19 01:18:04 【问题描述】:

我目前正在自己​​做一个小项目,以更好地学习 WPF,我问自己的一个问题是,如果我想遵循 MVVM 模式,不同视图之间的导航将如何工作。

我偶然发现了this question here answering my question,但不幸的是它似乎不起作用。不是显示我的视图,而是仅显示关联视图模型的命名空间。因此,例如,我看到的不是我的 LoginView,而是一个写有“JollyFinance.ViewModels.LoginViewModel”的白屏。

这是我的 MainWindow.xaml 代码:

<Window.Resources>
    <!-- Different pages -->
     <DataTemplate x:Key="LoginView" DataType="vm:LoginViewModel">
        <views:LoginView />
    </DataTemplate>
</Window.Resources>

<Window.DataContext>
    <vm:MainViewModel/>
</Window.DataContext>

<Grid>
    <ContentControl Content="Binding CurrentViewModel"/>
</Grid>

这是我的 MainViewModel.cs:

public class MainViewModel : BindableObject

    private ViewModelNavigationBase _currentViewModel;

    public MainViewModel()
    
        CurrentViewModel = new LoginViewModel();
    

    public ViewModelNavigationBase CurrentViewModel
    
        get  return _currentViewModel; 
        set
        
            if (_currentViewModel != value)
            
                _currentViewModel = value;
                RaisePropertyChanged();
            
        
    

我的 LoginViewModel.cs 文件:

    public LoginViewModel()
    
        LoginCommand = new RelayCommand(Login);
        NavigateCommand = new RelayCommand(Login);
    

    private void Login(object param)
    
        Popup codePopup = new Popup();
        TextBlock popupText = new TextBlock();
        popupText.Text = "Test";
        popupText.Background = Brushes.LightBlue;
        popupText.Foreground = Brushes.Blue;
        codePopup.Child = popupText;
    

    public String Username  get; set; 

    public String Password  get; set; 

    public ICommand LoginCommand  get; set; 

我的 LoginView.xaml 文件是一个 UserControl,由几个 ButtonsTextBlocks 组成。 BindableObject 只是我使用的一个抽象类,它实现了INotifyProperty 接口。 ViewModelNavigationBase 是我所有的视图模型都将继承的类;它暂时不包含任何内容。

我将如何解决此问题以显示我的视图而不是关联视图模型的字符串表示形式?

【问题讨论】:

【参考方案1】:

WPF 不支持以 string 作为类型标识符的隐式 DataTemplates。

您需要使用x:Type Markup Extension 来指定您的视图模型类型:

<DataTemplate DataType="x:Type vm:LoginViewModel">
    <views:LoginView />
</DataTemplate>

【讨论】:

不幸的是,这并不能解决我的问题。我将DataType="vm:LoginViewModel" 切换为DataType="x:Type vm:LoginViewModel",但我仍然只看到“JollyFinance.ViewModels.LoginViewModel”字符串而不是我的 LoginView 奇怪,使用 x:Type 应该可以工作。似乎 WPF 无法找到您的 DataTemplate。 &lt;ContentControl Content="Binding CurrentViewModel"/&gt;&lt;DataTemplate DataType="vm:LoginViewModel"&gt; 是否定义在同一个文件中?您可以尝试明确指定 DataTemplate 吗?因此,请尝试更改您的 &lt;DataTemplate x:Key="login"&gt; 并在 contentcontorl 中:&lt;ContentControl ContentTemplate="StaticResource login" ... 以查看模板对您的内容控件“可见”... 您没有正确应用内容模板。完整的代码是这样的 &lt;ContentControl ContentTemplate="StaticResource login" Content="Binding CurrentViewModel"/&gt; 我猜你已经尝试过了:&lt;ContentControl Content="StaticResource login"/&gt; 这就是你得到“System.Windows.DataTemplate”的原因。其他我无法在一个空项目中重现这个问题。 DataType="x:Type vm:LoginViewModel" 解决了这个问题。 不,不,这不是解决方案,这只是一个测试,以确定可能是什么问题。使用此ContentTemplate="StaticResource login",您将失去动态替换CurrentViewModel 并使用不同视图的能力。所以这还不是解决方案。注意到 WPF 中的更改,因此链接的文章也应该有效,而且我对 DataType="x:Type vm:LoginViewModel" 的回答也应该有效... 如果找到一个数据模板,内容控件应该使用该数据模板。所以显示字符串是不正常的。请检查这个简单的例子,你的代码正在使用我的修复:dropbox.com/s/vgzww3vn1ankg4r/WpfApplication1.zip?dl=0&lt;DataTemplate DataType="x:Type vm:LoginViewModel"&gt;【参考方案2】:

我终于找到了问题所在。出于某种原因,当您在 DataTemplate 上声明 x:Key 时,它会使 ContentControl 内容显示为字符串。我已经删除了 DataTemplate 的 x:Key,现在一切正常。我还必须应用 nemesv 的答案才能正常工作。

之前:

<DataTemplate x:Key="LoginView" DataType="vm:LoginViewModel">

之后(解决问题):

<DataTemplate DataType="x:Type vm:LoginViewModel">

【讨论】:

是的,你不能同时拥有x:KeyDataType,因为x:Key 覆盖了DataType 的“隐含性”。所以如果你x:Key你必须使用你的模板ContentTemplate="StaticResource LoginView" 是的,我注意到这是您的代码和我的代码之间的唯一区别,并尝试删除它并且它有效。再次感谢您的耐心和帮助! 我面临同样的问题: 是的,如果你想通过 key 引用它并且让它仍然作为该类型的默认 DataTemplate 工作,那么你可以删除 Key=...,创建第二个 DataTemplate with BasedOn=x :Type ... 和相同的DataType。

以上是关于使用 ContentControl 在 WPF 中显示视图不起作用的主要内容,如果未能解决你的问题,请参考以下文章

WPF - 将 ContentControl 添加到自定义画布

WPF MVVM 为啥使用 ContentControl + DataTemplate 视图而不是直接的 XAML 窗口视图?

带有 DataTemplate 的 ContentControl 不显示任何内容(WPF MVVM)

WPF 事件来捕获新添加的控件?

WPF ContentControl 宽度会增加,但在包裹在 ScrollViewer 中时不会缩小

c#WPF删除contentcontrol