【问题标题】:How to replace Maximize/RestoreDown icons of MetroWindow of MahApps如何替换 MahApps MetroWindow 的 Maximize/RestoreDown 图标
【发布时间】:2021-01-10 04:39:11
【问题描述】:

我在我的 WPF 应用程序中使用MahApps.Metro 并尝试将MetrowWindowMaximize/RestoreDown 图标更改为以下新的FullScreen/BackToWindow 图标:

问题:如何替换MetrowWindow默认的Maximize/RestoreDown图标?

备注:按照here的建议,我尝试了以下代码,但仍然显示旧样式 - 如下所示。我可能在这里遗漏了一些东西并且做得不对。新图标不是问题。我只需要知道如何用新的替换旧的。

<mah:MetroWindow x:Class="WPF_Mah_Metro_Test.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:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
        xmlns:iconPacks="http://metro.mahapps.com/winfx/xaml/iconpacks"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WPF_Mah_Metro_Test"
        mc:Ignorable="d"
        GlowBrush="{DynamicResource MahApps.Brushes.Accent}"
        ResizeMode="CanResizeWithGrip"
        WindowStartupLocation="CenterScreen"
        Height="450" Width="800">

    <mah:MetroWindow.WindowButtonCommands>
        <mah:WindowButtonCommands Template="{DynamicResource MahApps.Templates.WindowButtonCommands.Win10}" />
    </mah:MetroWindow.WindowButtonCommands>

    <Grid>
    </Grid>

【问题讨论】:

    标签: wpf xaml controltemplate mahapps.metro


    【解决方案1】:

    为了自定义窗口按钮,您必须为WindowButtonCommands 类型创建自定义控件模板。您可以复制from GitHub下方的默认控件模板之一。

    我采用了Win10 控件模板,并在PART_Max 按钮中调整了两件事:

    1. PART_MaxPathDataPath 更改为代表图标的适当路径,或将其替换为使用Segoe MDL2 Assets 字体并显示字形的TexBlock
    2. DataTrigger 更改为Maximized,以同样的方式设置相应的图标。

    在下面的示例中,我使用了TextBlock 方法,因为我没有图标的路径数据。请注意,Path 变体始终有效,而TextBlock 变体要求字体在您的系统上可用

    <ControlTemplate x:Key="MahApps.Templates.WindowButtonCommands.Custom"
                     TargetType="{x:Type mah:WindowButtonCommands}">
       <StackPanel Orientation="Horizontal">
          <Button x:Name="PART_Min"
                  Width="46"
                  AutomationProperties.AutomationId="Minimize"
                  AutomationProperties.Name="Minimize"
                  Command="{x:Static SystemCommands.MinimizeWindowCommand}"
                  Focusable="False"
                  IsEnabled="{Binding IsMinButtonEnabled, RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}}"
                  ToolTip="{Binding Minimize, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                  UseLayoutRounding="True">
             <Button.Visibility>
                <MultiBinding Converter="{x:Static converters:ResizeModeMinMaxButtonVisibilityConverter.Instance}"
                              ConverterParameter="MIN">
                   <Binding Mode="OneWay"
                            Path="ShowMinButton"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                   <Binding Mode="OneWay"
                            Path="UseNoneWindowStyle"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                   <Binding Mode="OneWay"
                            Path="ResizeMode"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                </MultiBinding>
             </Button.Visibility>
             <Path Width="10"
                   Height="10"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   Data="M0,0L10,0 10,1 10,1 1,1 0,1z"
                   Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
                   RenderOptions.EdgeMode="Aliased"
                   SnapsToDevicePixels="True"
                   Stretch="Uniform" />
          </Button>
          <Button x:Name="PART_Max"
                  Width="46"
                  AutomationProperties.AutomationId="MaximizeRestore"
                  AutomationProperties.Name="Maximize"
                  Command="{x:Static SystemCommands.MaximizeWindowCommand}"
                  Focusable="False"
                  IsEnabled="{Binding IsMaxRestoreButtonEnabled, RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}}"
                  ToolTip="{Binding Maximize, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                  UseLayoutRounding="True">
             <Button.Visibility>
                <MultiBinding Converter="{x:Static converters:ResizeModeMinMaxButtonVisibilityConverter.Instance}"
                              ConverterParameter="MAX">
                   <Binding Mode="OneWay"
                            Path="ShowMaxRestoreButton"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                   <Binding Mode="OneWay"
                            Path="UseNoneWindowStyle"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                   <Binding Mode="OneWay"
                            Path="ResizeMode"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                </MultiBinding>
             </Button.Visibility>
             <!--  normal state  -->
             <TextBlock x:Name="PART_MaxPath"
                        FontFamily="Segoe MDL2 Assets"
                        FontSize="16"
                        Text="&#xE740;" />
          </Button>
          <Button x:Name="PART_Close"
                  Width="46"
                  AutomationProperties.AutomationId="Close"
                  AutomationProperties.Name="Close"
                  Command="{x:Static SystemCommands.CloseWindowCommand}"
                  Focusable="False"
                  IsEnabled="{Binding RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}, Path=IsCloseButtonEnabled, Mode=OneWay}"
                  ToolTip="{Binding Close, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                  UseLayoutRounding="True">
             <Button.Visibility>
                <MultiBinding Converter="{x:Static converters:ResizeModeMinMaxButtonVisibilityConverter.Instance}"
                              ConverterParameter="CLOSE">
                   <Binding Mode="OneWay"
                            Path="ShowCloseButton"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                   <Binding Mode="OneWay"
                            Path="UseNoneWindowStyle"
                            RelativeSource="{RelativeSource AncestorType={x:Type mah:MetroWindow}}" />
                </MultiBinding>
             </Button.Visibility>
             <Path Width="10"
                   Height="10"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Center"
                   Data="F1M8.583,8L13,12.424 12.424,13 8,8.583 3.576,13 3,12.424 7.417,8 3,3.576 3.576,3 8,7.417 12.424,3 13,3.576z"
                   Fill="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
                   RenderOptions.EdgeMode="Aliased"
                   SnapsToDevicePixels="True"
                   Stretch="Uniform" />
          </Button>
       </StackPanel>
       <ControlTemplate.Triggers>
          <MultiDataTrigger>
             <MultiDataTrigger.Conditions>
                <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}, Path=IsCloseButtonEnabled}"
                           Value="True" />
                <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}, Path=IsAnyDialogOpen}"
                           Value="True" />
                <Condition Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}, Path=IsCloseButtonEnabledWithDialog}"
                           Value="False" />
             </MultiDataTrigger.Conditions>
             <Setter TargetName="PART_Close"
                     Property="IsEnabled"
                     Value="False" />
          </MultiDataTrigger>
          <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type mah:MetroWindow}}, Path=WindowState}"
                       Value="Maximized">
             <Setter TargetName="PART_Max"
                     Property="AutomationProperties.Name"
                     Value="Restore" />
             <Setter TargetName="PART_Max"
                     Property="Command"
                     Value="{x:Static SystemCommands.RestoreWindowCommand}" />
             <Setter TargetName="PART_Max"
                     Property="ToolTip"
                     Value="{Binding Restore, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}" />
             <Setter TargetName="PART_MaxPath"
                     Property="Text"
                     Value="&#xE73F;" />
          </DataTrigger>
          <Trigger Property="Theme"
                   Value="Light">
             <Setter TargetName="PART_Close"
                     Property="Style"
                     Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LightCloseButtonStyle}" />
             <Setter TargetName="PART_Max"
                     Property="Style"
                     Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LightMaxButtonStyle}" />
             <Setter TargetName="PART_Min"
                     Property="Style"
                     Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=LightMinButtonStyle}" />
          </Trigger>
          <Trigger Property="Theme"
                   Value="Dark">
             <Setter TargetName="PART_Close"
                     Property="Style"
                     Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DarkCloseButtonStyle}" />
             <Setter TargetName="PART_Max"
                     Property="Style"
                     Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DarkMaxButtonStyle}" />
             <Setter TargetName="PART_Min"
                     Property="Style"
                     Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=DarkMinButtonStyle}" />
          </Trigger>
       </ControlTemplate.Triggers>
    </ControlTemplate>
    

    将自定义WindowButtonCommands 模板MahApps.Templates.WindowButtonCommands.Custom 设置为MetroWindow,方法与您的问题相同。确保控件模板资源在范围内。

    <mah:MetroWindow.WindowButtonCommands>
       <mah:WindowButtonCommands Template="{StaticResource MahApps.Templates.WindowButtonCommands.Custom}" />
    </mah:MetroWindow.WindowButtonCommands>
    

    【讨论】:

    • 对于您的代码,我需要安装哪个NuGet 包?我收到错误消息:'clr-namespace' URI refers to a namespace 'MahApps.Metro.Converters' that could not be found。我安装了MahApps.Metro,并在&lt;mah:MetroWindow.....&gt; 中声明了xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"。我在 &lt;/MetroWindow&gt; 标签下方的 &lt;mah:MetroWindow.Resources&gt; &lt;ResourceDictionary&gt;...... 块中使用您的代码。
    • @nam 添加 XML 命名空间 xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"xmlns:converters="http://metro.mahapps.com/winfx/xaml/shared"
    • 添加建议的命名空间后,它现在可以工作了(谢谢)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-11
    • 2017-02-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多