简体   繁体   English

ContentControl.Content设置程序始终会覆盖内容模板的内容

[英]ContentControl.Content setter always overwrites the content template content

I am fighting with this issue for at least a couple of hours already. 我已经在这个问题上解决了至少两个小时。 I tried all possible solution I found on the net. 我尝试了在网上找到的所有可能的解决方案。 My latest is below and you will see that I am trying to add a simple MenuBar to the main Window control and present the content beneath. 我的最新文章在下面,您将看到我正在尝试向主Window控件添加一个简单的MenuBar并在下面显示内容。 My application is using MVVM and the view is assigned like this: 我的应用程序正在使用MVVM,并且按以下方式分配视图:
myMainWindow.Content = view; // this is what I cannot change

The soultion should be trivial but none works. 灵魂应该是微不足道的,但是没有用。 I tried with ContentTemplate, ContentPresenter, Style setter, all the variations with binding but nothing works as expected that is whenever myMainWindow.Content menu bar disappears. 我尝试使用ContentTemplate,ContentPresenter,Style setter,具有绑定的所有变体,但是每当myMainWindow.Content菜单栏消失时,都无法按预期工作。

None of the samples available on the internet does not actaully show an application with MenuBar and content at the same time. 互联网上提供的所有示例都无法同时显示具有MenuBar和内容的应用程序。

Is it so hard to add a menu bar in WPF application? 在WPF应用程序中添加菜单栏是否如此困难? I would be more than happy for any new suggestions. 对于任何新建议,我都会感到非常高兴。
Thanks in advance. 提前致谢。

<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>

Your application isn't really using MVVM. 您的应用程序不是真正使用MVVM。 At best it might be sort of halfway using MVVM. 最好情况下,使用MVVM可能只是半途而废。

Meanwhile, all the XAML inside your <Window> tag in your main window XAML file is the window's Content . 同时,主窗口XAML文件中<Window>标记内的所有XAML都是窗口的Content And you are explicitly replacing that with some random object, so of course it's not there any more. 而且您已将其显式替换为一些随机对象,因此当然不再存在。

You aren't giving much detail, but you need to assign your main viewmodel to the Window's DataContext and not assign anything to the window's Content . 您不需要提供太多细节,但是您需要将主viewmodel分配给Window的DataContext ,而不要将任何Content分配给Window的Content

You didn't say what view is in this line of code, so I have no idea what you were trying to do there: 您没有说这行代码中的view ,所以我不知道您正在尝试做什么:

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

Is view a viewmodel, or a view? view是视图模型还是视图? Whatever it is, don't do that. 无论是什么,都不要这样做。

You could assign your main viewmodel to the Window's datacontext in XAML, too: 您也可以在XAML中将主视图模型分配给Window的数据上下文:

<Window ... >

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

<!-- ... -->

</Window>

Then bind your viewmodel to the Content property of a ContentPresenter . 然后将您的viewmodel绑定到ContentPresenterContent属性。 There's no need to apply the window's content via a template here so I eliminated that part. 这里不需要通过模板应用窗口的内容,因此我省去了那部分。 The only template you need in this snipppet is the DataTemplate which displays your viewmodel in the ContentPresenter . 在此片段中,您唯一需要的模板是DataTemplate ,它在ContentPresenter显示您的视图模型。

The layout here is copied verbatim from MainWindow.xaml in a project I recently wrote. 我最近在一个项目中从MainWindow.xaml 逐字复制了这里的布局。 I replaced my main menu with yours and omitted my Window.Resources . 我用您的替换了主菜单,并省略了Window.Resources That's the only change. 那是唯一的变化。

<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>

A simple {Binding} with no Source or Path etc. properties will bind to the DataContext . 没有SourcePath等属性的简单{Binding}将绑定到DataContext The ContentPresenter will inherit its DataContext from the Window that contains it. ContentPresenter将从包含它的Window继承其DataContext

Then, if you've got a data template defined with a DataType the same as your main viewmodel, that data template will be instantiated in that ContentPresenter . 然后,如果您使用与主视图模型相同的DataType定义了一个数据模板,则该数据模板将在ContentPresenter实例化。

"Bind" doesn't mean "assign in code-behind". “绑定”并不意味着“在后台分配代码”。 It means to use the System.Windows.Data.Binding class. 这意味着要使用System.Windows.Data.Binding类。 The easiest way to do that is in the XAML as I've shown above. 如上所示,最简单的方法是在XAML中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM