您的位置:首页 > 其它

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

2009-05-07 10:39 148 查看
原文链接: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<DependencyProperty, object> 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<DependencyProperty, object> buttonPropertyValues =

new Dictionary<DependencyProperty, object>()

{

{ 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/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: