以编程方式更改WPF样式中的颜色 - 应用程序资源

时间:2015-10-29 18:30:01

标签: c# wpf xaml

我已经简化了一些代码。 Style定义更符合我在我正在处理的实际程序中所拥有的内容,而不是原始样本的所有自动生成的绒毛 - 对于Window Resource样本和我想要移动到的内容w / Application Resource样本。

我还在应用程序资源示例中“点缀”了基于appColors.appColor的{​​{1}}绑定。我也玩了一些w / DependencyObject,但还没有让它正常工作。我在INotifyPropertyChangedApp类中尝试了这一点。

基于Changing Colors in WPF Style Programmatically我能够使用转换器和DependencyProperty值以编程方式更改文本框的前景色。使用本地Windows资源生成的代码如下:

MainWindow.xaml:

AppColors

MainWindow.xaml.cs

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Name="LocalWindow" x:Class="ColorLocal.MainWindow"
        xmlns:local="clr-namespace:ColorLocal"
        Title="MainWindow" Height="122.321" Width="269.87">
    <Window.Resources>
        <local:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
        <Style x:Key="LocalTextBoxStyle" BasedOn="{x:Null}" TargetType="{x:Type TextBox}">
            <Setter Property="Foreground" Value="{Binding ElementName=LocalWindow, Path=localColor, Converter={StaticResource ColorToSolidColorBrushConverter}}"/>
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
        </Style>
    </Window.Resources>
    <Grid>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Style="{DynamicResource LocalTextBoxStyle}"/>
        <Button x:Name="btnRed" Content="Red" HorizontalAlignment="Left" Margin="10,47,0,0" VerticalAlignment="Top" Width="75" Click="btnRed_Click"/>
        <Button x:Name="btnGreen" Content="Green" HorizontalAlignment="Left" Margin="90,47,0,0" VerticalAlignment="Top" Width="75" Click="btnGreen_Click"/>
        <Button x:Name="btBlue" Content="Blue" HorizontalAlignment="Left" Margin="170,47,0,0" VerticalAlignment="Top" Width="75" Click="btBlue_Click"/>
        <Button x:Name="btnNewWindow" Content="New Window" HorizontalAlignment="Left" Margin="170,10,0,0" VerticalAlignment="Top" Width="75" Click="btnNewWindow_Click"/>

    </Grid>
</Window>

此代码生成一个对话框,其中TextBox的文本最初为紫色,3个按钮标记为红色绿色,&amp; 蓝色,另一个标记为新窗口的按钮。按相应的颜色按钮,更改TextBox中文本的颜色。 “新窗口”按钮不执行任何操作。

我现在要将其转换为应用程序资源,我可以将其分配给不同窗口上的所有控件,并在整个程序中进行颜色更改。我在附加的代码段中进行了详细的更改。我最初在App.xaml.cs代码中使用DependencyObject值时遇到了问题,但发现了另一篇关于它的帖子。但是,即使在MainWindow TextBox上,TextBox前景色仍然是黑色的(我还没有围绕New Window按钮按下编码逻辑)。

任何想法/方向都将不胜感激。

我已更新代码示例此提供的代码更符合

的实际编码

的App.xaml

namespace ColorLocal
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public static readonly DependencyProperty localColorProperty = DependencyProperty.Register("localColor", typeof(Color?), typeof(MainWindow), new PropertyMetadata(Colors.Purple));

        public Color? localColor
        {
            get { return (Color?)GetValue(localColorProperty); }
            set { SetValue(localColorProperty, value); }
        }

        public MainWindow()
        {
            InitializeComponent();
        }

        private void btnRed_Click(object sender, RoutedEventArgs e)
        {
            this.localColor = Colors.Red;
        }

        private void btnGreen_Click(object sender, RoutedEventArgs e)
        {
            this.localColor = Colors.Green;
        }

        private void btBlue_Click(object sender, RoutedEventArgs e)
        {
            this.localColor = Colors.Blue;
        }

        private void btnNewWindow_Click(object sender, RoutedEventArgs e)
        {

        }
    }

    public class ColorToSolidColorBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Color? desiredColor = value as Color?;
            if (desiredColor != null)
            {
                return new SolidColorBrush(desiredColor.Value);
            }

            //Return here your default
            return DependencyProperty.UnsetValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }
}

App.xaml.cs

<Application
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero" x:Name="LocalApp" x:Class="ColorApp.App"
             xmlns:local="clr-namespace:ColorApp"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <local:ColorToSolidColorBrushConverter x:Key="ColorToSolidColorBrushConverter" />
        <Style x:Key="AppTextBoxStyle" TargetType="{x:Type TextBox}" BasedOn="{x:Null}">
            <Setter Property="Foreground" Value="{Binding appColors.appColor, Converter={StaticResource ColorToSolidColorBrushConverter}, ElementName=LocalApp}"/>
            <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
        </Style>
    </Application.Resources>
</Application>

MainWindow.xaml

namespace ColorApp
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App : Application
    {
        public AppColors appColors = new AppColors();
    }

    public class AppColors : DependencyObject
    {
        public static readonly DependencyProperty appColorProperty = DependencyProperty.Register("appColor",
                                typeof(Color?), typeof(AppColors), new PropertyMetadata(Colors.Purple));

        public Color? appColor
        {
            get { return (Color?)this.GetValue(appColorProperty); }
            set { this.SetValue(appColorProperty, value); }
        }
    }

    public class ColorToSolidColorBrushConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            Color? desiredColor = value as Color?;
            if (desiredColor != null)
            {
                return new SolidColorBrush(desiredColor.Value);
            }

            //Return here your default
            return DependencyProperty.UnsetValue;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return DependencyProperty.UnsetValue;
        }
    }
}

MainWindow.xaml.cs

<Window x:Class="ColorApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="122.321" Width="269.87">
    <Grid>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="10,10,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Style="{DynamicResource AppTextBoxStyle}"/>
        <Button x:Name="btnRed" Content="Red" HorizontalAlignment="Left" Margin="10,47,0,0" VerticalAlignment="Top" Width="75" Click="btnRed_Click"/>
        <Button x:Name="btnGreen" Content="Green" HorizontalAlignment="Left" Margin="90,47,0,0" VerticalAlignment="Top" Width="75" Click="btnGreen_Click"/>
        <Button x:Name="btBlue" Content="Blue" HorizontalAlignment="Left" Margin="170,47,0,0" VerticalAlignment="Top" Width="75" Click="btBlue_Click"/>
        <Button x:Name="btnNewWindow" Content="New Window" HorizontalAlignment="Left" Margin="170,10,0,0" VerticalAlignment="Top" Width="75" Click="btnNewWindow_Click"/>

    </Grid>
</Window>

1 个答案:

答案 0 :(得分:0)

您的绑定不正确

在App.xaml中,您需要将前台绑定更改为:

<Setter Property="Foreground" Value="{Binding Path=appColors.appColor, Converter={StaticResource ColorToSolidColorBrushConverter}, Source={x:Static Application.Current}}"/>

以你的风格。

将App.xaml.cs中的App类更改为:

public partial class App : Application
{

    public AppColors appColors { get; set; }

    protected override void OnStartup(StartupEventArgs e)
    {
        this.appColors = new AppColors();

        base.OnStartup(e);
    }
}

因此它将被初始化并正确设置。

尝试过它并且像魅力一样。