【问题标题】:.NET WPF Global dynamic styles configuration.NET WPF 全局动态样式配置
【发布时间】:2022-11-12 00:38:50
【问题描述】:

几天来,我一直在尝试做一些类似全局样式配置的事情。 它应该如何工作?

我想要一个类来控制组件的视觉样式。 例如。:

在设置页面中:我正在选择我自己的颜色,以及所有绑定到特定变量的组件,这些变量将存储该颜色,更改背景颜色或边框。我希望拥有全局样式,并且能够在鼠标悬停时控制按钮的颜色。

我正在尝试使用全局单例类和静态类,但它不起作用。我也不想复制组件,因为那不是重点。

这就是我尝试做的方式(看看风格的背景)。

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:config="clr-namespace:Manager.Data.Configuration">
    
    <Style x:Key="FocusVisual">
        <Setter Property="Control.Template">
            <Setter.Value>
                <ControlTemplate>
                    <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <SolidColorBrush x:Key="Button.Static.Background" Color="#FFDDDDDD"/>
    <SolidColorBrush x:Key="Button.Static.Border" Color="#FF707070"/>
    <SolidColorBrush x:Key="Button.MouseOver.Background" Color="#FFBEE6FD"/>
    <SolidColorBrush x:Key="Button.MouseOver.Border" Color="#FF3C7FB1"/>
    <SolidColorBrush x:Key="Button.Pressed.Background" Color="#FFC4E5F6"/>
    <SolidColorBrush x:Key="Button.Pressed.Border" Color="#FF2C628B"/>
    <SolidColorBrush x:Key="Button.Disabled.Background" Color="#FFF4F4F4"/>
    <SolidColorBrush x:Key="Button.Disabled.Border" Color="#FFADB2B5"/>
    <SolidColorBrush x:Key="Button.Disabled.Foreground" Color="#FF838383"/>

    <ControlTemplate x:Key="ButtonControlTemplate" TargetType="{x:Type Button}">
        <Border
            x:Name="border"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Background="{TemplateBinding Background}"
            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="{StaticResource Button.MouseOver.Background}"/>
                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.MouseOver.Border}"/>
            </Trigger>
            <Trigger Property="IsPressed" Value="true">
                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Pressed.Background}"/>
                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Pressed.Border}"/>
            </Trigger>
            <Trigger Property="IsEnabled" Value="false">
                <Setter Property="Background" TargetName="border" Value="{StaticResource Button.Disabled.Background}"/>
                <Setter Property="BorderBrush" TargetName="border" Value="{StaticResource Button.Disabled.Border}"/>
                <Setter Property="TextElement.Foreground" TargetName="contentPresenter" Value="{StaticResource Button.Disabled.Foreground}"/>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

    <Style x:Key="ButtonStyle" TargetType="{x:Type Button}">
        <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
        <Setter Property="Background" Value="{Binding StylesConfig.ButtonBackgroundColor}"/>
        <Setter Property="BorderBrush" Value="Red"/>
        <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" Value="{StaticResource ButtonControlTemplate}"/>
    </Style>

</ResourceDictionary>

StylesConfig 类只是具有静态 Brush 值的简单静态类。我还尝试制作单例(然后我输入了&lt;Setter Property="Background" Value="{Binding StylesConfig.Instance.ButtonBackgroundColor}"/&gt;),这个类看起来像:

public class StylesConfig : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    private static StylesConfig instance;
    private Brush buttonBackgroundBrush;

    public static StylesConfig Instance
    {
        get
        {
            if (instance == null)
                instance = new StylesConfig();

            return instance;
        }
    }

    public Brush ButtonBackgroundColor
    {
        get
        {
            return buttonBackgroundBrush;
        }
        set
        {
            buttonBackgroundBrush = value;
            OnPropertyChanged(nameof(ButtonBackgroundColor));
        }
    }

    private StylesConfig()
    {
        ButtonBackgroundColor = new SolidColorBrush(Colors.Red);
    }

    private void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;

        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }

}

它可以很容易地完成并且不会生成大量代码吗?

【问题讨论】:

    标签: c# wpf binding styles resourcedictionary


    【解决方案1】:

    您可以尝试将 StylesConfig 保持为单例,并在 xaml 的根目录中使用键声明它:

    xmlns:myNamespace="clr-namespace:namespace.of.stylesconfig"
    
    <x:Static x:Key="StylesConfig" Member="myNamespace:StylesConfig.Instance" />
    

    然后在您的 xaml 中其他位置的任何按钮上:

    <Button Background="{Binding ButtonBackgroundColor, Source={StaticResource StylesConfig}, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
    

    如果这不起作用,则值得考虑使用 DynamicResource,并使用 Application.Current.FindResource("Dynamic_Resource_Key") 从资源管理器类切换某个资源下的值。一个简单的例子是:

    <SolidColorBrush Key="My_Resource" Color="Yellow" />
    
    <Button Background="{DynamicResource My_Resource}" />
    

    然后,随时从代码中的其他地方:

    if(Application.Current.TryFindResource("My_Resource") is SolidColorBrush brush) { brush.Background = Colors.Red; }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-18
      • 1970-01-01
      • 2012-01-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多