我正在接近WPF(特别是我正在使用MVVM),并且我正在尝试创建将在整个应用程序中使用的自定义窗口样式。我想要做的是创建一个基本样式,定义窗口颜色,边框,图标,标题等。窗口可以调整大小或对话框,所以我使用WindowChrome设置"可调整大小的窗口&# 34;默认情况下,它具有最小化,最大化和关闭按钮,并且实际上可以调整大小。对于Login窗口,我希望有一个使用基本样式的窗口,但是用户无法调整大小或最大化它,因此最大化按钮根本不可见。我一直在研究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的正确方法是什么?
提前感谢您的帮助。
答案 0 :(得分:1)
我将定义布尔附加属性local:WindowExt.ShowMaximizeButton
等,默认值为true。在ControlTemplate中,我将这些应用程序应用于带有TemplateBindings的按钮,并通过样式设置器(或直接在XAML中的Window元素上)设置它们。
以下是ShowMaximizeButton
的示例;其他人用不同的名字是一样的。复制并粘贴依赖项属性定义时,请注意在每个出现的位置更新属性名称。我使用片段来创建它们,以尽量减少粗心错误。
public static class WindowExt
{
public static bool GetShowMaximizeButton(Window obj)
{
return (bool)obj.GetValue(ShowMaximizeButtonProperty);
}
public static void SetShowMaximizeButton(Window obj, bool value)
{
obj.SetValue(ShowMaximizeButtonProperty, value);
}
public static readonly DependencyProperty ShowMaximizeButtonProperty =
DependencyProperty.RegisterAttached("ShowMaximizeButton", typeof(bool), typeof(WindowExt),
new PropertyMetadata(true));
}
确保它位于定义窗口控件模板之前的某个位置,在同一资源字典中:
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
窗口控制模板中的最大化按钮。除了将这些适当绑定的可见性属性添加到按钮之外,不会对控件模板进行任何更改。注意Binding路径中的parens;这些是至关重要的,因为它是单个属性的多部分标识符。
<ToggleButton
Style="{StaticResource MaximizeWindowButtonStyle}"
Command="{Binding MaximizeCommand}"
Visibility="{TemplateBinding local:WindowExt.ShowMaximizeButton, Converter={StaticResource BooleanToVisibilityConverter}}"
/>
并在窗口样式中使用:
<Style TargetType="Window">
<Setter Property="local:WindowExt.ShowMaximizeButton" Value="True" />
</Style>
请注意,附加属性是控件本身的依赖项属性,与任何DataContexts或viewmodel无关。