WPF应用程序中所有窗口的相同菜单栏或工具栏

时间:2018-11-28 14:05:42

标签: c# wpf

我想用菜单栏创建一个wpf应用程序。菜单栏具有一些可单击的元素,这将打开一个新窗口。因为每个窗口上的菜单栏都相同,所以我只想创建一次菜单栏。

我在这里阅读了如何创建菜单栏(What is the accepted way to get a main window with menubar and toolbar in WPF?):

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        x:Name="self"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Menu Grid.Row="0">
            <MenuItem Header="File">
                <MenuItem Header="Open" />
                <MenuItem Header="Close" />
            </MenuItem>
        </Menu>
        <ToolBar Grid.Row="1">
            <Button Content="Foo" />
            <Button Content="Bar" />
        </ToolBar>
    </Grid>
</Window>

我还阅读了有关所有wpf Windows的相同页眉和页脚的问题: Same header & footer in all WPF windows。他们在那里建议一个用户控件。

问题How to make a Template Window in WPF?不能解决我的问题。是否可以将clicklistener添加到模板?我不想在每个窗口上实现所有clicklistener。我的菜单栏/工具栏仅打开其他一些窗口。该解决方案仅适用于播放静态内容。

这种问题的最佳实践是什么?

2 个答案:

答案 0 :(得分:1)

您可以使用DataTemplates。

DataTemplate:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                xmlns:local="clr-namespace:WpfApplication1">
    <DataTemplate DataType="{x:Type local:MenuBar}">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition Height="Auto" />
                <RowDefinition Height="*" />
            </Grid.RowDefinitions>
            <Menu Grid.Row="0">
                <MenuItem Header="File">
                    <MenuItem Header="Open" />
                    <MenuItem Header="Close" />
                </MenuItem>
            </Menu>
            <ToolBar Grid.Row="1">
                <Button Content="Foo" />
                <Button Content="Bar" />
            </ToolBar>
        </Grid>
    </DataTemplate>
</ResourceDictionary>

后面的代码:

namespace WpfApplication1
{
    public class MenuBar
    {
        //some logic here
    }
}

在代码中的使用示例:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="self"
    Title="MainWindow" Height="350" Width="525">
    <ContentPresenter Content="{Binding MenuBar}"/>
</Window>

菜单栏是菜单栏类型的属性。

答案 1 :(得分:1)

您可以在定义窗口模板的地方创建样式。

<Style x:Key="MyWindowStyle" TargetType="Window">
    //Some other shared properties
    <Setter Property="..." Value="..."/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <StackPanel>
                    //This will represent a header/toolbar
                    <StackPanel />
                    <ContentPresenter />
                    //This will represent a footer
                    <StackPanel />
                </StackPanel>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

将该样式添加到应用程序资源中:

<Application x:Class="Wpf.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Application.Resources>
        <Style x:Key="MyWindowStyle" TargetType="Window">
            //...
        </Style>
    </Application.Resources>
</Application>

您可以随后使用它:

<Window x:Class="Wpf.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:viewModels="clr-namespace:Wpf.ViewModels"
        mc:Ignorable="d"
        Style="{StaticResource MyWindowStyle}"> //We apply that style to this window

    <TextBlock Text="This will be put in 'ContentPresenter' between those stackpanels"/>

</Window>

如果工具栏/标题很复杂,则可以将其拉到单独的用户控件中。
如果您想拥有共享代码隐藏功能的“基础”窗口,请查看https://docs.qameta.io/allure/