【问题标题】:Application.Resources in WPF from Template Copy - How can I get order into it?模板复制中的 WPF 中的 Application.Resources - 我怎样才能获得订单?
【发布时间】:2021-04-14 15:49:44
【问题描述】:

我对 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.xaml 或 CancelButton.xaml,并在需要时重新导入它们。 这可能吗?

【问题讨论】:

    标签: c# wpf xaml controltemplate


    【解决方案1】:

    创建一个新的资源字典项目 > 添加新项目... > 资源字典(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 标记扩展替换所有以画笔为目标的 StaticResource 和 x: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。由于画笔在基本样式中不可用,因此在查找过程中可以在派生样式中找到它们。有关资源查找的更多信息,请参阅Overview of XAML resources (WPF .NET)。

    查找在由设置属性的元素定义的资源字典中检查请求的键 [...] 查找向上遍历逻辑树到父元素及其资源字典。这个过程一直持续到到达根元素。 [...]

    这是一个用于您的 Save 和 Cancel 按钮的资源字典示例,带有惰性着色。

    <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>
    

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

    【讨论】:

    • 这是一个非常高质量的答案!谢谢!
    【解决方案2】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-25
      • 1970-01-01
      • 2012-10-02
      • 2013-12-30
      • 1970-01-01
      • 2020-03-31
      相关资源
      最近更新 更多