• 快速浏览Silverlight3 Beta: SystemColor(系统颜色)


         原文链接:Silverlight 3 – System Colours  
        
         Silverlight 3 中加入了一个名为“SystemColors”类,其包括如下属性;
        
         

        如果我创建一个Silverlight 应用,并在其中放入一个button(按钮)的话:  

     <Button
                
    Content="Click Me"
                FontSize
    ="24"
                HorizontalAlignment
    ="Center"
                VerticalAlignment
    ="Center" />

                
        会显示如下内容:
        
        
        你会看到在左侧我启动了一个计算器. 如果此时我在Windows中修改了我的系统颜色时,比如
    使用”高亮对比”这种设置时;

        
        
        这时会显示:
        
        

         也就是计算器和FireFox会跟随着系统颜色而变化,但Silverlight 应用却不会。它还是老样子,
    不受系统颜色设置的影响.

         如果Silverlight应用能按用户或开发者设想的去应用这些设置(系统颜色)该多好呀。
       
         现在,SystemColors就可以实现(尽管其仅有少数一些静态属性可以使用,且当用户修改设置时
    还无法修改(通知)当前显示界面等等)。    
      
         不过,我认为如果用户刷新浏览器的话(或可以点击Silverlight UI上的一个按钮来通知当前应用
    已修改了WINDOWS主题的话),这些就不是什么主要的缺失了。It’s liveable.

        抱着这种想法,我打算显露出SystemColors的一些静态属性,将其作为非静态属性以便于在XAML
    使用.

        下面这是相关的尝试 :-)
       

    public class MySystemColours
    {
      
    public Brush ControlTextBrush
      {
        
    get
        {
          
    if (controlTextBrush == null)
          {
            controlTextBrush 
    = new SolidColorBrush(SystemColors.ControlTextColor);
          }
          
    return (controlTextBrush);
        }
      }
      Brush controlTextBrush;
    }

      

         而相应的Xaml内容如下:   

    <UserControl
        
    x:Class="SilverlightApplication36.MainPage"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local
    ="clr-namespace:SilverlightApplication36">
        
    <UserControl.Resources>
            
    <local:MySystemColours x:Key="mySystemColours" />
        
    </UserControl.Resources>
        
    <Grid
            
    x:Name="LayoutRoot">
            
    <Grid.Resources>
            
    </Grid.Resources>
            
    <Button
                
    Foreground="{Binding Source={StaticResource mySystemColours},Path=ControlTextBrush}"
                Content
    ="Click Me"
                FontSize
    ="24"
                HorizontalAlignment
    ="Center"
                VerticalAlignment
    ="Center" />
        
    </Grid>
    </UserControl>


         现在,看上去已经差不多了。但我并不真想在每个控件实现上显式的设置“Foreground”和
    “Background”属性,我想用一个Style来实现。

         那么,我可能要创建一个Style,其使用了诸如ControlTextBrush等的brushes,以便于应用到
    Buttons, CheckBoxes等等UI元素上.

        这也就导致了我的第二个尝试,其 XAML代码如下;

    <UserControl
        
    x:Class="SilverlightApplication36.MainPage"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local
    ="clr-namespace:SilverlightApplication36">
        
    <UserControl.Resources>
            
    <local:MySystemColours x:Key="mySystemColours" />
            
    <Style
                
    x:Key="mySystemStyle"
                TargetType
    ="Button">
                
    <Setter
                    
    Property="Foreground"
                    Value
    ="{Binding Source={StaticResource mySystemColours},Path=ControlTextBrush}" />
            
    </Style>
        
    </UserControl.Resources>
        
    <Grid
            
    x:Name="LayoutRoot">
            
    <Grid.Resources>
            
    </Grid.Resources>
            
    <Button
                
    Style="{StaticResource mySystemColours}"
                Content
    ="Click Me"
                FontSize
    ="24"
                HorizontalAlignment
    ="Center"
                VerticalAlignment
    ="Center" />
        
    </Grid>
    </UserControl>


        除了不能实际运行,其它看起来还都不错 :-) 问题在于我要在绑定一个 Brush值。但在Silverlight
    中你不能绑定这个Brushes或 Colors值, 你只能将这些绑定应用到从FrameworkElement派生出来的元素上。
    在这个论坛中有相关的主题,如果别人有不同的做法请通知我,以便我能够及时了解到.

      
        那该怎么办呢?
       
        好吧, 我们可以数据绑定方式来为Styles设置Brush和Color,但却不能数据绑定setters。也许我能在
    运行时创建一个完整的style 并添加这些属性(到元素中);

    public class MySystemStyles
      {
        
    public Style ButtonStyle
        {
          
    get
          {
            
    if (buttonStyle == null)
            {
              buttonStyle 
    = MakeStyle(typeof(Button));
            }
            
    return (buttonStyle);
          }
        }
        
    static Style MakeStyle(Type t)
        {
          Style style 
    = new Style(t);

          
    foreach (var item in propertiesValues)
          {
            style.Setters.Add(
    new Setter(item.Key, item.Value));
          }
          
    return (style);
        }
        
    static Dictionary<DependencyProperty, object> propertiesValues =
          
    new Dictionary<DependencyProperty, object>()
          {
            { Control.ForegroundProperty, 
    new SolidColorBrush(SystemColors.ControlTextColor) },
            { Control.BackgroundProperty, 
    new SolidColorBrush(SystemColors.ControlColor) }
          };

        Style buttonStyle;
      }

      
      
         现在,除了默认的Button模版不依赖于Foreground 和 Background 之外,活干的差不多了。
    它可以使用更多的颜色和一个BorderBrush,但也有一些颜色在Button的属性上是无效的。具我
    所知也就能修改这两种属性.

         我需要另外一个Button版本,其使用Foreground, Background 和 BorderBrush. 那我要如何
    组合这个style呢?

         我想到可以使用BasedOn style,其XAML如下;
       

    <UserControl.Resources>
         
    <local:MySystemStyles
             
    x:Key="mySystemStyles" />
         
    <Style
             
    x:Key="buttonStyle"
             BasedOn
    ="{Binding Source={StaticResource mySystemStyles},Path=ButtonStyle}">


             
         在运行时无法工作( BasedOn 绑定时IE报错).

         也许可以变换一下思路,当它在运行时创建一个style时,我可以通知 MySystemStyles 类。它应该
    基于当前的style。看起来有些麻烦但却可行;

    public class MySystemStyles
    {
      
    public Style BasedOnButtonStyle
      {
        
    get
        {
          
    return (basedOnButtonStyle);
        }
        
    set
        {
          basedOnButtonStyle 
    = value;
        }
      }    
      
    public Style ButtonStyle
      {
        
    get
        {
          
    if (buttonStyle == null)
          {
            buttonStyle 
    = MakeStyle(typeof(Button), basedOnButtonStyle, buttonPropertyValues);
          }
          
    return (buttonStyle);
        }
      }
      
    static Style MakeStyle(Type t, Style basedOnStyle, Dictionary&lt;DependencyProperty, object&gt; propertyValues)
      {
        Style style 
    = new Style(t);

        style.BasedOn 
    = basedOnStyle;

        
    foreach (var item in propertyValues)
        {
          style.Setters.Add(
    new Setter(item.Key, item.Value));
        }
        
    return (style);
      }
      
    static Dictionary&lt;DependencyProperty, object&gt; buttonPropertyValues =
        
    new Dictionary&lt;DependencyProperty, object&gt;()
        {
          { Control.ForegroundProperty, 
    new SolidColorBrush(SystemColors.ControlTextColor) },
          { Control.BackgroundProperty, 
    new SolidColorBrush(SystemColors.ControlColor) },
          { Button.BorderBrushProperty, 
    new SolidColorBrush(SystemColors.ActiveBorderColor) }
        };

      Style buttonStyle;
      Style basedOnButtonStyle;
    }

         相应的XAML 如下;

    <UserControl
        
    x:Class="SilverlightApplication36.MainPage"
        xmlns
    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x
    ="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:vsm
    ="clr-namespace:System.Windows;assembly=System.Windows"
        xmlns:local
    ="clr-namespace:SilverlightApplication36">
        
    <UserControl.Resources>
            
    <Style
                
    x:Key="buttonStyle" TargetType="Button">
                
    <Setter
                    
    Property="Template">
                    
    <Setter.Value>
                        
    <ControlTemplate
                            
    TargetType="Button">
                            
    <Grid>
                                
    <vsm:VisualStateManager.VisualStateGroups>
                                    
    <vsm:VisualStateGroup
                                        
    x:Name="CommonStates">
                                        
    <vsm:VisualState
                                            
    x:Name="Normal" />
                                        
    <vsm:VisualState
                                            
    x:Name="MouseOver">
                                            
    <Storyboard>
                                                
    <DoubleAnimationUsingKeyFrames
                                                    
    Storyboard.TargetName="BackgroundAnimation"
                                                    Storyboard.TargetProperty
    ="Opacity">
                                                    
    <SplineDoubleKeyFrame
                                                        
    KeyTime="0"
                                                        Value
    ="1" />
                                                
    </DoubleAnimationUsingKeyFrames>
                                            
    </Storyboard>
                                        
    </vsm:VisualState>
                                        
    <vsm:VisualState
                                            
    x:Name="Pressed">
                                            
    <Storyboard>
                                                
    <DoubleAnimationUsingKeyFrames
                                                    
    Storyboard.TargetName="BackgroundAnimation"
                                                    Storyboard.TargetProperty
    ="Opacity">
                                                    
    <SplineDoubleKeyFrame
                                                        
    KeyTime="0"
                                                        Value
    ="1" />
                                                
    </DoubleAnimationUsingKeyFrames>
                                            
    </Storyboard>
                                        
    </vsm:VisualState>
                                        
    <vsm:VisualState
                                            
    x:Name="Disabled">
                                            
    <Storyboard>
                                                
    <DoubleAnimationUsingKeyFrames
                                                    
    Storyboard.TargetName="DisabledVisualElement"
                                                    Storyboard.TargetProperty
    ="Opacity">
                                                    
    <SplineDoubleKeyFrame
                                                        
    KeyTime="0"
                                                        Value
    =".55" />
                                                
    </DoubleAnimationUsingKeyFrames>
                                            
    </Storyboard>
                                        
    </vsm:VisualState>
                                    
    </vsm:VisualStateGroup>
                                    
    <vsm:VisualStateGroup
                                        
    x:Name="FocusStates">
                                        
    <vsm:VisualState
                                            
    x:Name="Focused">
                                            
    <Storyboard>
                                                
    <DoubleAnimationUsingKeyFrames
                                                    
    Storyboard.TargetName="FocusVisualElement"
                                                    Storyboard.TargetProperty
    ="Opacity">
                                                    
    <SplineDoubleKeyFrame
                                                        
    KeyTime="0"
                                                        Value
    ="1" />
                                                
    </DoubleAnimationUsingKeyFrames>
                                            
    </Storyboard>
                                        
    </vsm:VisualState>
                                        
    <vsm:VisualState
                                            
    x:Name="Unfocused" />
                                    
    </vsm:VisualStateGroup>
                                
    </vsm:VisualStateManager.VisualStateGroups>
                                
    <Border
                                    
    x:Name="Background"
                                    Background
    ="{TemplateBinding Background}"
                                    BorderBrush
    ="{TemplateBinding BorderBrush}"
                                    BorderThickness
    ="{TemplateBinding BorderThickness}"
                                    CornerRadius
    ="3">
                                    
    <Grid
                                        
    Margin="1"
                                        Background
    ="{TemplateBinding Background}">
                                        
    <Border
                                            
    x:Name="BackgroundAnimation"
                                            Opacity
    ="0"
                                            Background
    ="{TemplateBinding Background}" />
                                    
    </Grid>
                                
    </Border>
                                
    <ContentPresenter
                                    
    x:Name="contentPresenter"
                                    HorizontalAlignment
    ="{TemplateBinding HorizontalContentAlignment}"
                                    Margin
    ="{TemplateBinding Padding}"
                                    VerticalAlignment
    ="{TemplateBinding VerticalContentAlignment}"
                                    Content
    ="{TemplateBinding Content}"
                                    ContentTemplate
    ="{TemplateBinding ContentTemplate}" />
                                
    <Rectangle
                                    
    x:Name="DisabledVisualElement"
                                    Fill
    ="#FFFFFFFF"
                                    RadiusX
    ="3"
                                    RadiusY
    ="3"
                                    IsHitTestVisible
    ="false"
                                    Opacity
    ="0" />
                                
    <Rectangle
                                    
    x:Name="FocusVisualElement"
                                    Stroke
    ="{TemplateBinding BorderBrush}"
                                    StrokeThickness
    ="1"
                                    RadiusX
    ="2"
                                    RadiusY
    ="2"
                                    Margin
    ="1"
                                    IsHitTestVisible
    ="false"
                                    Opacity
    ="0" />
                            
    </Grid>
                        
    </ControlTemplate>
                    
    </Setter.Value>
                
    </Setter>
            
    </Style>
            
    <local:MySystemStyles
                
    x:Key="mySystemStyles" 
                BasedOnButtonStyle
    ="{StaticResource buttonStyle}"/>
        
    </UserControl.Resources>
        
    <Grid
            
    x:Name="LayoutRoot">
            
    <Grid.Resources>
            
    </Grid.Resources>
            
    <Button
                
    Style="{Binding Source={StaticResource mySystemStyles},Path=ButtonStyle}"
                Content
    ="Click Me"
                FontSize
    ="24"
                HorizontalAlignment
    ="Center"
                VerticalAlignment
    ="Center" />
        
    </Grid>
    </UserControl>


         现在,它可以按我起初的想法,很好的运行了。当我在Windows中修改我的颜色主题时并刷新当前的
    Silverlight 应用,按钮会去获取已修改的系统颜色.

         但是,目前在按钮上只有三个属性可以设置. 我需要为每个控件设置一系列的styles,然后再去扩展
    MySystemStyles 类,诸如一些:ComboBoxStyle, TreeViewStyle, TextBoxStyle 属性等等。它也
    必须包括诸如BasedOnComboBoxStyle 或 BasedOnTreeViewStyle属性等等.

        哎…虽然可以工作,但应该还有更好的变法吧?

        Anyone got ideas? :-)
       
       
       
        原文链接:http://www.cnblogs.com/daizhj/archive/2009/05/06/1450455.html

        译者: daizhj, 代震军

        Tags: silverlight,system color,系统主题,theme
       
        网址:
    http://daizhj.cnblogs.com/  

     

       

  • 相关阅读:
    解决软件升级过程中GAC发生的问题.
    Appupdater 组件的一个问题.
    == 和 != 有点靠不主,建议在进行比较的时候尽可能的使用Equals
    从资源文件中提取Icon对象到Image对象的小技巧。
    arcgis flex开发备忘
    IIS服务器的系统事件日志常见问题汇总(更新中)
    WebSphere6.1配置应用程序
    Android Preference使用
    Oracle无法删除当前已连接的用户
    SSH环境搭建
  • 原文地址:https://www.cnblogs.com/daizhj/p/1450455.html
Copyright © 2020-2023  润新知