WPF动态改变主题颜色

简介:

国内的WPF技术先行者周银辉曾介绍过如何动态改变应用程序的主题样式,今天我们来介绍一种轻量级的改变界面风格的方式——动态改变主题色。
程序允许用户根据自己的喜好来对界面进行配色,这种技术在很多软件中都有应用,比如这款名为AirPlay的音乐播放器软件:

 

 

下面我们就来自己动手实现这种技术:
首先在App.xaml文件中定义一个键值为“color”的单色笔刷,这个笔刷就是可以被用户改变的动态资源:

<SolidColorBrush x:Key="color" Color="SkyBlue" />

然后来设计这样一个界面:

我们让用户通过4个滑块来分别定制颜色的ARGB值,其完整代码为:

<Grid>

    <Grid.RowDefinitions>

        <RowDefinition Height="28" />

        <RowDefinition Height="28" />

        <RowDefinition Height="28" />

        <RowDefinition Height="28" />

        <RowDefinition Height="*" />

    </Grid.RowDefinitions>

    <Grid.ColumnDefinitions>

        <ColumnDefinition Width="65*" />

        <ColumnDefinition Width="213*" />

    </Grid.ColumnDefinitions>

    <Label Grid.Row="0" HorizontalContentAlignment="Right">透明度:</Label>

    <Label Grid.Row="1" HorizontalContentAlignment="Right">红色:</Label>

    <Label Grid.Row="2" HorizontalContentAlignment="Right">绿色:</Label>

    <Label Grid.Row="3" HorizontalContentAlignment="Right">蓝色:</Label>

    <Slider Grid.Row="0" Grid.Column="1" Margin="3" Name="a" SmallChange="1" LargeChange="15" Maximum="255" Value="255" />

    <Slider Grid.Row="1" Grid.Column="1" Margin="3" Name="r" SmallChange="1" LargeChange="15" Maximum="255" Value="255" />

    <Slider Grid.Row="2" Grid.Column="1" Margin="3" Name="g" SmallChange="1" LargeChange="15" Maximum="255" Value="255" />

    <Slider Grid.Row="3" Grid.Column="1" Margin="3" Name="b" SmallChange="1" LargeChange="15" Maximum="255" Value="255" />

    <Button Grid.Column="1" Grid.Row="4" HorizontalAlignment="Left" Margin="3,5,0,5" Name="button1" Width="75" Click="button1_Click">更新颜色</Button>

</Grid>

需注意,要把滑块的最大值设为255

然后回到App.xaml中,我们来定义窗口、标签及按钮的样式:

窗口样式代码如下:

<Style x:Key="window" TargetType="Window">

    <Setter Property="OverridesDefaultStyle" Value="true" />

    <Setter Property="AllowsTransparency" Value="true" />

    <Setter Property="SnapsToDevicePixels" Value="true" />

    <Setter Property="WindowStyle" Value="None" />

    <Setter Property="Template">

        <Setter.Value>

            <ControlTemplate TargetType="Window">

                <Border BorderBrush="{DynamicResource color}" BorderThickness="3" CornerRadius="5" Padding="4">

                    <Border BorderBrush="{DynamicResource color}" BorderThickness="3" CornerRadius="5" Background="{DynamicResource color}">

                        <Border BorderBrush="#1000" BorderThickness="3" CornerRadius="5" Padding="6">

                            <Border.Background>

                                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                                    <GradientStop Color="#3FFF" Offset="0.5" />

                                    <GradientStop Color="#1666" Offset="0.5" />

                                </LinearGradientBrush>

                            </Border.Background>

                            <ContentPresenter />

                        </Border>

                    </Border>

                 </Border>

            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

定义样式为几个Border进行嵌套,在最底层引用的之前定义的单色笔刷,在上层用低不透明度的白色和黑色覆盖以产生不同的层次效果。

标签样式为:

<Style TargetType="Label">

    <Setter Property="Foreground" Value="#AAFFFFFF" />

</Style>

按钮样式为:

<Style TargetType="Button">

    <Setter Property="Template">

        <Setter.Value>

            <ControlTemplate TargetType="Button">

                <Border Background="{DynamicResource color}" CornerRadius="3">

                    <Border BorderThickness="2" CornerRadius="3" Padding="{TemplateBinding Padding}">

                        <Border.Background>

                            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                                <GradientStop Color="#6FFF" Offset="0" />

                                <GradientStop Color="#2000" Offset="1" />

                            </LinearGradientBrush>

                        </Border.Background>

                        <Border.BorderBrush>

                            <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                                <GradientStop Color="#1000" Offset="0" />

                                <GradientStop Color="#4000" Offset="1" />

                            </LinearGradientBrush>

                        </Border.BorderBrush>

                        <TextBlock TextAlignment="Center" Foreground="#AFFF"><ContentPresenter /></TextBlock>

                    </Border>

                </Border>

            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

其原理与窗口样式相同。

然后回到主界面设计窗口,设置窗体的样式:

Style="{StaticResource window}"

接下来编辑后台代码,首先为窗体增加事件处理以提供拖动功能:

MouseLeftButtonDown="Window_MouseLeftButtonDown"

后台事件处理代码:

private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)

{

    this.DragMove();

}

为按钮增加事件处理来更新界面颜色:

private void button1_Click(object sender, RoutedEventArgs e)

{

    更新颜色(Color.FromArgb((byte)a.Value, (byte)r.Value, (byte)g.Value, (byte)b.Value));

}

“更新颜色”方法代码如下:

public void 更新颜色(Color c)

{

    this.Resources.Remove("color");

    this.Resources.Add("color"new SolidColorBrush(c));

}

此方法首先移除资源“color”,然后再添加一个同名的新笔刷,这样就完成了动态替换工作。

现在编译并执行程序,可以看到如下效果:

源代码下载


本文转自斯克迪亚博客园博客,原文链接:http://www.cnblogs.com/SkyD/archive/2008/09/02/1281975.html,如需转载请自行联系原作者

相关文章
|
C# 数据格式 XML
WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树)
原文:WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树) 一、WPF对象级(Window对象)资源的定义与查找 实例一: StaticR...
8046 0
|
9月前
|
移动开发 开发框架 网络协议
WPF+ASP.NET SignalR实现动态折线图
WPF+ASP.NET SignalR实现动态折线图
82 0
|
IDE 编译器 C#
WPF实现强大的动态公式计算
数据库可以定义表不同列之间的计算公式,进行自动公式计算,但如何实现行上的动态公式计算呢?行由于可以动态扩展,在某些应用场景下将能很好的解决实际问题。本文就探讨一下如何在WPF中实现一种基于行字段的动态公式计算。
990 0
WPF实现强大的动态公式计算
|
C#
WPF中让TextBlock每一个字符显示不同的颜色
原文:WPF中让TextBlock每一个字符显示不同的颜色 XAML代码: R G B ...
1636 0
|
C#
WPF圆角按钮与触发颜色变化
原文:WPF圆角按钮与触发颜色变化 ...
1541 0
|
C#
WPF 颜色转换
原文:WPF 颜色转换 从字符串到画刷: var converter = new System.Windows.Media.BrushConverter(); var brush = (Brush)converter.
894 0
|
C# 程序员 测试技术
WPF之动态换肤
原文:WPF之动态换肤 如何实现换肤呢,对于复杂的换肤操作,如,更换按钮样式、窗口样式等,我们需要写多个资源字典来表示不同的皮肤,通过动态加载不同的资源字典来实现换肤的效果;对于简单的换肤操作,如更改背景颜色、设置窗体透明度,这种换肤操作,我们就不能使用上面的方法了,这个时候,我们只要在一个全局对象中添加几个属性,如背景颜色、前景颜色、窗体透明度等,然后,再绑定这几个属性就能达到我们想要的效果。
951 0
|
C#
WPF - 模板查看工具:Show Me The Template及如何查看第三方主题
原文:WPF - 模板查看工具:Show Me The Template及如何查看第三方主题   在学习WPF的模板(DataTemplate、ItemsPanelTemplate、ControlTemplate)时,经常会想看看WPF内建的控件模板。
1573 0
|
C# Windows
让你的WPF程序在Win7下呈现Win8风格主题
原文:让你的WPF程序在Win7下呈现Win8风格主题 今天在Win8下使用了一个我之前写的一个WPF程序的时候,发现现在也支持Win8效果了(记得以前的.net 4.0的版本是不支持的)。由于WPF的控件是自绘的,并不受系统主题所控制,也就是说.net 4.5中是附带了Win8主题样式文件的,按理说这个风格在Win7下也可以使用的。
1200 0
|
C# Windows
WPF 4 动态覆盖图标(Dynamic Overlay Icon)
原文:WPF 4 动态覆盖图标(Dynamic Overlay Icon)      在《WPF 4 开发Windows 7 任务栏》一文中我们学习了任务栏的相关开发内容,同时也对覆盖图标(Overlay Icon)功能进行了一些介绍,其中覆盖图标是以静态方式呈现的。
1089 0