ContentControl.Content setter始终覆盖内容模板内容

时间:2016-03-30 16:25:40

标签: c# wpf mvvm

我已经和这个问题争斗了至少几个小时了。我尝试了在网上找到的所有可能的解决方案。我的最新信息如下,您将看到我正在尝试将一个简单的MenuBar添加到主窗口控件并在其下方显示内容。我的应用程序使用MVVM,视图分配如下:
 myMainWindow.Content = view; // this is what I cannot change

灵魂应该是微不足道的,但没有效果。我尝试使用ContentTemplate,ContentPresenter,Style setter,带有绑定的所有变体,但是当myMainWindow.Content菜单栏消失时,没有任何工作正常。

互联网上提供的所有样本都不能同时显示带有MenuBar和内容的应用程序。

在WPF应用程序中添加菜单栏是否如此困难? 任何新的建议我都会非常高兴 提前谢谢。

<window:BaseWindow x:Class="OneTwoThree.Manager.MainWindow"
                   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                   xmlns:window="clr-namespace:Xsell.Client.Common;assembly=Xsell.Client.Common"
                   Title="{Binding Title}"
                   Width="1020"
                   Height="750"
                   Closed="AppClosed"
                   Icon="app.ico"
                   Loaded="AppLoaded">
    <Window.Resources>
        <Style TargetType="{x:Type Window}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type Window}">
                        <Grid>
                            <DockPanel>
                                <Menu IsMainMenu="True" DockPanel.Dock="Top">
                                    <MenuItem Header="Admin">
                                        <MenuItem Header="Manage Labels"></MenuItem>
                                    </MenuItem>
                                </Menu>
                                <ContentPresenter DockPanel.Dock="Bottom"/>
                            </DockPanel>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
</window:BaseWindow>

1 个答案:

答案 0 :(得分:0)

您的应用程序实际上并未使用MVVM。充其量可能是使用MVVM的一半。

同时,主窗口XAML文件中<Window>标记内的所有XAML都是窗口Content。并且您明确地用一些随机对象替换它,所以当然它不再存在了。

您没有提供太多详细信息,但是您需要将主视图模型分配给窗口DataContext,而不是将任何内容分配给窗口的Content

你没有在这行代码中说出view是什么,所以我不知道你在那里做了什么:

myMainWindow.Content = view; // this is what I cannot change

view是视图模型还是视图?无论是什么,都不要这样做。

您也可以将主视图模型分配给XAML中的Window的datacontext:

<Window ... >

<Window.DataContext>
    <local:MyViewModel />
</Window.DataContext>

<!-- ... -->

</Window>

然后将您的viewmodel绑定到Content的{​​{1}}属性。没有必要通过模板在这里应用窗口的内容,所以我删除了那部分。此snipppet中唯一需要的模板是ContentPresenter,它会在DataTemplate中显示您的viewmodel。

此处的布局在我最近编写的项目中从ContentPresenter复制 verbatim 。我用你的主菜单替换了我的主菜单,省略了我的MainWindow.xaml。这是唯一的变化。

Window.Resources

没有<Window ...> <DockPanel> <Menu IsMainMenu="True" DockPanel.Dock="Top"> <MenuItem Header="Admin"> <MenuItem Header="Manage Labels"></MenuItem> </MenuItem> </Menu> <Grid> <ContentPresenter Content="{Binding}" /> </Grid> </DockPanel> </Window> {Binding}等属性的简单Source将绑定到PathDataContext将从包含它的ContentPresenter继承其DataContext

然后,如果您使用与主视图模型相同的Window定义数据模板,则该数据模板将在DataType中实例化。

“Bind”并不意味着“在代码隐藏中分配”。这意味着使用System.Windows.Data.Binding类。最简单的方法是在XAML中,如上所示。