WPF中的动态换肤

 
在WPF中换肤异常方便,只有将窗口资源设置为不同的ResourceDictionary就可以了。而且可以换得很彻底,甚至是彻底改变整个窗口上控件的种类,大小,个数等。
 
下面是一个实现。
建立一个叫做Blue.xaml的文件,在上面写入
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
    <StackPanel x:Key="Root" Height="120">
    <Button Background="Blue" Height="40"/>
    <Button Background="Blue" Height="40"/>
    <Button Background="Blue" Height="40"/>
    </StackPanel>
</ResourceDictionary>
然后建立一个叫Green.xaml的文件,在上面写入
 
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    >
    <Grid x:Key="Root" Width="170" Height="90">
   
    <Grid.ColumnDefinitions>   
    <ColumnDefinition Width="80"/>
    <ColumnDefinition Width="80"/>
    </Grid.ColumnDefinitions>
   
    <Grid.RowDefinitions>
    <RowDefinition Height="40"/>
    <RowDefinition Height="40"/>
    </Grid.RowDefinitions>
   
    <Button Background="Green" Grid.Column="0" Grid.Row="0"/>
    <Button Background="Green" Grid.Column="1" Grid.Row="0"/>
    <Button Background="Green" Grid.Column="0" Grid.Row="1"/>
    <Button Background="Green" Grid.Column="1" Grid.Row="1"/>
   
    </Grid>
</ResourceDictionary>
然后是主窗口的xaml
<Window x:Class="SkinTest2.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="150" Width="300" Content="{DynamicResource Root}">
</Window>
将窗口的Content设置为一个动态资源Root就行了。
添加一个新类
Blue,在它的构造函数中设置将Blue.xaml中的ResourceDictionary设置给窗口
            ResourceDictionary resDic = new ResourceDictionary();
            resDic.Source = new Uri("Blue.xaml", UriKind.Relative);
            window.Resources = resDic;
 
StackPanel stackPanel = window.Content as StackPanel;
通过转型来得到Blue中的StackPanel, 这种方法看起来有的粗鲁,但是没有想到别的办法
            for (int i = 0; i < stackPanel.Children.Count; i++)
            {
                button[i] = stackPanel.Children[i] as Button;
                button[i].Click += handler[i];
            }
遍历stackPanel的子元素,把Button一个个地取出来添加事件。没法子。在写Blue.xaml中的ResourceDictionary的时候不能给资源StackPanel的子元素再设置x:key了
添加一个Green类,同样这么干。
 
最后测试一下,在主窗口中放入一个托盘按钮,方便一会切换皮肤
        private Blue blue;
        private Green green;
        private System.Windows.Forms.NotifyIcon notifyIcon;
}
 
        public Window1()
        {
            InitializeComponent();
 
            notifyIcon = new System.Windows.Forms.NotifyIcon();
            notifyIcon.Icon = Properties.Resources.icon2;
 
            System.Windows.Forms.ContextMenu contextMenu = new System.Windows.Forms.ContextMenu();
给contextMenu添加两个菜单项
 
            contextMenu.MenuItems.Add("Blue").Click +=
                ((sender, e) =>
                {
                    if (blue == null)
                    {
                        blue = new Blue(this);
                        green = null;
                    }
                });
 
            contextMenu.MenuItems.Add("green").Click +=
                ((sender, e) =>
                {
                    if(green == null)
                    {
                        green = new Green(this);
                        blue = null;
                    }
                });
这里用了3.0中的Lambda表达式,看起来还不赖,比起boost中的那个类库级的Lambda看起来自然多了。
 
            notifyIcon.ContextMenu = contextMenu;
            notifyIcon.Visible = true;
右击托盘图标,可以任意切换。当然换得这么彻底也很少见,都换了,和新建一个窗口有啥区别: )
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值