【发布时间】:2023-03-30 15:38:01
【问题描述】:
我正在接近 WPF(特别是我正在研究 MVVM)并且我正在尝试创建一个将在整个应用程序中使用的自定义窗口样式。我想要做的是创建一个基本样式,它将定义窗口颜色、边框、图标、标题等。窗口可以调整大小或类似对话框,所以我使用 WindowChrome 设置具有最小化的“可调整大小的窗口” ,默认情况下最大化和关闭按钮,实际上是可调整大小的。对于登录窗口,我希望有一个使用基本样式的窗口,但用户无法调整大小或最大化它,因此根本不应该看到最大化按钮。我一直在研究 BasedOn 样式,我可以成功地覆盖属性,但我无法定义哪些按钮可以或不可以在窗口内可见。所以我要做的是更改嵌套的 UI 控件(在本例中为 StackPanel)。
这是我创建的基本样式,目前它包含所有窗口属性和窗口按钮(我尽量评论它):
<ControlTemplate TargetType="{x:Type Window}" x:Key="DefaultWindowsTemplate">
<!-- The outer border of the Window -->
<Border Padding="{Binding OuterMarginSizeThickness, FallbackValue=10}">
<!-- The inner border of the Window and the Window itself, from the contour line to the shadow -->
<Grid>
<Border CornerRadius="{Binding WindowCornerRadius}"
BorderBrush="{StaticResource AlizarinBrush}"
BorderThickness="{Binding OutlineBorderThickness, FallbackValue=1}"
Background="{StaticResource VoidnessBrush}">
<Border.Effect>
<DropShadowEffect Color="{StaticResource Voidness}" ShadowDepth="0" Opacity="1"/>
</Border.Effect>
</Border>
<!-- The Container grid, composed by the title bar and the content area -->
<Grid>
<!-- Rows definition -->
<Grid.RowDefinitions>
<RowDefinition Height="{Binding TitleHeight, FallbackValue=30}"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- Title bar row that contains icon, title and window buttons -->
<Grid Margin="{Binding TitleHeightMargin}"
Background="{StaticResource VoidnessBrush}"
Grid.Row="0"
Panel.ZIndex="1"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<!-- Window icon -->
<Button Margin="5 5 0 0"
Style="{StaticResource WindowIconButtonStyle}"
Command="{Binding MenuCommand}">
<Image Source="/Images/Logos/khm_logo_titlebar.png"/>
</Button>
<!-- Window title -->
<TextBlock Grid.Column="1"
Foreground="{StaticResource ConcreteBrush}"
Margin="15 5 0 0"
TextAlignment="Center"
VerticalAlignment="Center"
HorizontalAlignment="Left"
Text="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Title, FallbackValue='Window Title'}"/>
<!-- Window buttons - THIS IS THE CONTROL I WANT TO DEFINE INSIDE 'BASED ON' STYLES, WHERE I WILL NOT HAVE THE MAXIMIZE BUTTON -->
<StackPanel Grid.Column="2"
Orientation="Horizontal">
<Button Style="{StaticResource WindowButtonsStyle}"
Content="0"
Command="{Binding MinimizeCommand}"/>
<ToggleButton Style="{StaticResource MaximizeWindowButtonStyle}"
Command="{Binding MaximizeCommand}"/>
<Button Style="{StaticResource WindowCloseButtonStyle}"
Content="r"
Command="{Binding CloseCommand}"/>
</StackPanel>
</Grid>
<!-- The Window content -->
<Grid Margin="1 5 0 0" Grid.Row="1">
<ContentPresenter/>
</Grid>
</Grid>
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="Window" x:Key="DefaultWindowsStyle">
<Setter Property="Template" Value="{StaticResource DefaultWindowsTemplate}"/>
<Setter Property="MinWidth" Value="{Binding WindowMinWidth}"/>
<Setter Property="MinHeight" Value="{Binding WindowMinHeight}"/>
<Setter Property="WindowStyle" Value="None"/>
<Setter Property="AllowsTransparency" Value="True"/>
</Style>
然后我开始编辑基本样式如下(当然是在另一个 XAML 文件中):
<Style TargetType="Window" x:Key="DialogWindowsStyle" BasedOn="{StaticResource DefaultWindowsStyle}">
<!-- REMOVE THE MAXIMIZE BUTTON INSIDE THE NESTED STACK PANEL -->
</Style>
那么在使用相同样式的同时编辑部分 UI 的正确方法是什么?
提前感谢您的帮助。
【问题讨论】:
-
我将定义布尔附加属性
local:MyWindow.ShowMaximizeButton等,默认值为true,然后在模板中使用TemplateBinding,并根据需要将它们应用到样式中。如果需要可以提供示例,它只是一堆样板代码。 -
@EdPlunkett 不幸的是,附加属性的概念对我来说是相当新的,所以非常感谢一个例子。无论如何,这是我可以开始四处寻找的东西,所以谢谢!
标签: c# wpf xaml user-interface styles