Application.Resources 在 WPF 中从模板复制 - 我怎样才能得到订单?

Application.Resources in WPF from Template Copy - How can I get order into it?

我是 WPF 的新手。我需要更改按钮鼠标悬停颜色,所以我右键单击按钮,然后复制模板。所以 Visual Studio 在我的 App.xaml 中添加了很多新行,我现在可以在其中设置按钮的设计,如下所示:

<Application x:Class="Thermologger.Start.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Thermologger.Start"
             Startup="Application_Startup">
    <!--StartupUri="MainWindow.xaml"-->
             
    <Application.Resources>

        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <SolidColorBrush x:Key="Button.Static.Background" Color="#ff609d9f"/>
        <SolidColorBrush x:Key="Button.Static.Border" Color="#ff609d9f"/>
        <SolidColorBrush x:Key="Button.Static.Foreground" Color="white"/>
        <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#cf609d9f"/>
        <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#cf609d9f"/>
        <SolidColorBrush x:Key="Button.Pressed.Background" Color="#cf609d9f"/>
        <SolidColorBrush x:Key="Button.Pressed.Border" Color="black"/>
        <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>

还有更多!

所以现在我想用另一个按钮和其他颜色来做到这一点 - 所以我又做了同样的事情,那时候 visual studio 开始像这样编号:

<SolidColorBrush x:Key="Button.Static.Background" Color="#ff609d9f"/>
<SolidColorBrush x:Key="Button.Static.Background1" Color="#ff609d9f"/>

因为有很多自动生成的行,所以我的 App.xaml 大约有 500 多行,只是按钮中的一些颜色变化。

所以我的问题是,我现在怎样才能做得更好?

它可以帮助我将每个按钮提取到它自己的文件中,以获得更清晰的文件,如 SaveButton.xamlCancelButton.xaml,并在我需要时重新导入它们。 这可能吗?

我认为您可以在自定义按钮样式中使用类似于以下内容的样式,或者创建针对某个按钮的通用样式,然后在您想要的按钮中使用它。

          <Style.Triggers>                                       
                <Trigger Property="IsMouseOver"   Value="True">
                    <Setter Property="Foreground" Value="Green" />
                </Trigger>                
            </Style.Triggers>    

或者,您可以使用 MouseEnter 和 MouseLeave 事件并手动更改后台代码中的颜色,但这通常不是首选

创建新资源字典项目 > 添加新项目... > 资源字典(WPF) 并将其命名为 SaveButton.xaml。将资源复制到这个新的资源字典。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

   <Style x:Key="FocusVisual">
      <Setter Property="Control.Template">
         <Setter.Value>
            <ControlTemplate>
               <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            </ControlTemplate>
         </Setter.Value>
      </Setter>
   </Style>
   <SolidColorBrush x:Key="Button.Static.Background" Color="#ff609d9f"/>

   <!-- ...other resources. -->

</ResourceDictionary>

也为其他按钮样式创建字典并将它们添加到应用程序资源中。

<Application x:Class="Thermologger.Start.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:Thermologger.Start"
             Startup="Application_Startup">
   <Application.Resources>
      <ResourceDictionary>
         <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="SaveButton.xaml"/>
            <!-- ...other resource dictionaries. -->
         </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary>
   </Application.Resources>
</Application>

如果您只想更改颜色,则不需要复制按钮样式和模板。一种方法是为您的不同风格分离画笔,如下所示:

  • 创建资源字典,例如ButtonStyles.xaml.
  • 在那里提取默认按钮样式和模板。
  • 将按钮样式 x:Key 重命名为 BaseButtonStyle
  • DynamicResource 标记扩展替换所有指向画笔的 StaticResourcex:Static 引用(在运行时解析资源 - 这里是画笔)
  • 根据您的中性基本样式 BaseButtonStyle 为其中一个按钮创建样式 将所有画笔 从基本样式移动到 Resources 的新样式。
  • 自定义画笔以获得自定义样式。
  • 使用每个新按钮的画笔复制此样式,替换其 x:Key 并调整画笔。

像上面一样将资源字典添加到应用程序资源中。现在,您可以使用 x:Key.

在代码中显式引用每个特殊按钮样式
<StackPanel>
   <Button Style="{DynamicResource SaveButtonStyle}" Content="Test"/>
   <Button Style="{DynamicResource CancelButtonStyle}" Content="Test"/>
</StackPanel>

At runtime the brushes will be resolved searching up the logical tree. Since the brushes are not available in the base style, they are found in your derived style in the lookup process. For more information about resource lookup, refer to Overview of XAML resources (WPF .NET).

The lookup checks for the requested key within the resource dictionary defined by the element that sets the property [...] The lookup traverses the logical tree upward to the parent element and its resource dictionary. This process continues until the root element is reached. [...]

这里有一个这样的资源字典示例,用于您的 保存取消 按钮,带有惰性着色。

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    
   <Style x:Key="FocusVisual">
      <Setter Property="Control.Template">
         <Setter.Value>
            <ControlTemplate>
               <Rectangle Margin="2" StrokeDashArray="1 2" SnapsToDevicePixels="true" StrokeThickness="1" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
            </ControlTemplate>
         </Setter.Value>
      </Setter>
   </Style>
   <Style x:Key="BaseButtonStyle" TargetType="{x:Type Button}">
      <Setter Property="FocusVisualStyle" Value="{DynamicResource FocusVisual}"/>
      <Setter Property="Background" Value="{DynamicResource Button.Static.Background}"/>
      <Setter Property="BorderBrush" Value="{DynamicResource Button.Static.Border}"/>
      <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
      <Setter Property="BorderThickness" Value="1"/>
      <Setter Property="HorizontalContentAlignment" Value="Center"/>
      <Setter Property="VerticalContentAlignment" Value="Center"/>
      <Setter Property="Padding" Value="1"/>
      <Setter Property="Template">
         <Setter.Value>
            <ControlTemplate TargetType="{x:Type Button}">
               <Border x:Name="border" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" SnapsToDevicePixels="true">
                  <ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
               </Border>
               <ControlTemplate.Triggers>
                  <Trigger Property="IsDefaulted" Value="true">
                     <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource {x:Static SystemColors.HighlightBrushKey}}"/>
                  </Trigger>
                  <Trigger Property="IsMouseOver" Value="true">
                     <Setter Property="Background" TargetName="border" Value="{DynamicResource Button.MouseOver.Background}"/>
                     <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Button.MouseOver.Border}"/>
                  </Trigger>
                  <Trigger Property="IsPressed" Value="true">
                     <Setter Property="Background" TargetName="border" Value="{DynamicResource Button.Pressed.Background}"/>
                     <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Button.Pressed.Border}"/>
                  </Trigger>
                  <Trigger Property="IsEnabled" Value="false">
                     <Setter Property="Background" TargetName="border" Value="{DynamicResource Button.Disabled.Background}"/>
                     <Setter Property="BorderBrush" TargetName="border" Value="{DynamicResource Button.Disabled.Border}"/>
                     <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{DynamicResource Button.Disabled.Foreground}"/>
                  </Trigger>
               </ControlTemplate.Triggers>
            </ControlTemplate>
         </Setter.Value>
      </Setter>
   </Style>

   <Style x:Key="SaveButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
      <Style.Resources>
         <SolidColorBrush x:Key="Button.Static.Background" Color="Red"/>
         <SolidColorBrush x:Key="Button.Static.Border" Color="Blue"/>
         <SolidColorBrush x:Key="Button.MouseOver.Background" Color="Yellow"/>
         <SolidColorBrush x:Key="Button.MouseOver.Border" Color="Purple"/>
         <SolidColorBrush x:Key="Button.Pressed.Background" Color="Green"/>
         <SolidColorBrush x:Key="Button.Pressed.Border" Color="Orange"/>
         <SolidColorBrush x:Key="Button.Disabled.Background" Color="Brown"/>
         <SolidColorBrush x:Key="Button.Disabled.Border" Color="Aqua"/>
         <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="AntiqueWhite"/>
      </Style.Resources>
   </Style>

   <Style x:Key="CancelButtonStyle" TargetType="{x:Type Button}" BasedOn="{StaticResource BaseButtonStyle}">
      <Style.Resources>
         <SolidColorBrush x:Key="Button.Static.Background" Color="Black"/>
         <SolidColorBrush x:Key="Button.Static.Border" Color="DarkSlateGray"/>
         <SolidColorBrush x:Key="Button.MouseOver.Background" Color="DimGray"/>
         <SolidColorBrush x:Key="Button.MouseOver.Border" Color="DarkGray"/>
         <SolidColorBrush x:Key="Button.Pressed.Background" Color="LightGray"/>
         <SolidColorBrush x:Key="Button.Pressed.Border" Color="Gray"/>
         <SolidColorBrush x:Key="Button.Disabled.Background" Color="GhostWhite"/>
         <SolidColorBrush x:Key="Button.Disabled.Border" Color="DimGray"/>
         <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="LightSlateGray"/>
      </Style.Resources>
   </Style>

</ResourceDictionary>

当然,如果你愿意,你也可以把它们分成几个不同的资源字典。