如何在Silverlight工具包主题上创建样式?

时间:2011-04-13 13:07:02

标签: silverlight xaml silverlight-4.0 themes silverlight-toolkit

可以这样做吗?

在我的xaml代码中,我有一些带有样式的ComboBox,定义如下:

<Style x:Key="comboProjectsStyle"
       TargetType="ComboBox">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid>
                    <TextBlock Text="{Binding Path=Name}"
                               FontSize="14" />
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>
<Style x:Key="comboDataSourcesStyle"
       TargetType="ComboBox">
    <Setter Property="ItemTemplate">
        <Setter.Value>
            <DataTemplate>
                <Grid>
                    <TextBlock Text="{Binding Path=DescriptiveName}"
                               FontSize="14" />
                </Grid>
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>
<ComboBox Width="300"
          Style="{StaticResource comboProjectsStyle}" />
<ComboBox Width="300"
          Style="{StaticResource comboDataSourcesStyle}" />

Silverlight主题(例如:ExpressionDark)正确应用于每个控件,除了我已定义样式的控件,如上所述。

据我所知,在WPF中我们可以使用x:使用“BasedOn”属性在Silverlight主题上为我们的Style设置样式。但是,使用Silverlight 4似乎无法实现这一点。

有关如何处理此事的任何想法?

谢谢!

3 个答案:

答案 0 :(得分:1)

将ItemTemplate声明为资源而不是样式,然后将应用主题样式。

<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    x:Class="Silverlight_Spike.MainPage"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">
    <UserControl.Resources>
        <DataTemplate x:Key="DataTemplate1">
            <Grid>
                <TextBlock Text="{Binding Name}" FontSize="14" />
            </Grid>
        </DataTemplate>
    </UserControl.Resources>

    <ComboBox ItemTemplate="{StaticResource DataTemplate1}" />

</UserControl>

答案 1 :(得分:0)

删除样式中的键:

    <Style TargetType="ComboBox">
                <Setter Property="ItemTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Grid>
                                <TextBlock Text="{Binding Path=Name}" FontSize="14" />
                            </Grid>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
        </Style>
    <Style x:Key="comboProjectsStyle" TargetType="ComboBox">
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Grid>
                            <TextBlock Text="{Binding Path=Name}" FontSize="14" />
                        </Grid>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
    </Style>

    <Style x:Key="comboDataSourcesStyle" TargetType="ComboBox">
            <Setter Property="ItemTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <Grid>
                            <TextBlock Text="{Binding Path=DescriptiveName}" FontSize="14" />
                        </Grid>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
    </Style>

    <ComboBox Width="300" Style="{StaticResource comboProjectsStyle}" />
    <ComboBox Width="300" Style="{StaticResource comboDataSourcesStyle}" />

<ComboBox Width="300" />
<ComboBox Width="300" />
<ComboBox Width="300" />

基本上这意味着你在上面制作的样式适用于目标类型的ComboBox,它没有命名,因此没有设置样式的每个Combobox都会将其作为默认值继承。

<强>更新 正如您所看到的,所有3种样式可以在同一资源中共存,每当您使用命名样式时,它将应用于所述控件,但是对于最后三个组合框,所有3种样式都将具有没有键的样式。这就是如何在主题中完成的,就像来自MS的JetPack皮肤一样。

希望这会有所帮助。

答案 2 :(得分:0)

嗨,这不是完全使用basedOn,但通过使用转换器,我们可以实现将自定义样式基于主题的目标。我们就是这样做的。

  1. 展示主题并将其放置在可以将其绑定到样式的位置。

  2. 创建一个值转换器来转换您正在使用的样式。此转换器将返回基于主题的样式,因此这是一个片段。

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (parameter is Style)
        {
            Style retStyle = parameter as Style;
            Theme themeContainer;
            if (value is Theme)
                themeContainer = value as Theme; //(App.Current as App).AppTheme;
            else
                themeContainer = (App.Current as App).AppTheme; 
    
            if (themeContainer != null)
            {
                foreach (DictionaryEntry i in themeContainer.ThemeResources)
                {
                    if (i.Value is Style)
                    {
                        Style t = i.Value as Style;
                        if (t.TargetType == retStyle.TargetType)
                        {
                            Style newStyle = new Style();
                            newStyle.TargetType = retStyle.TargetType;
                            newStyle.BasedOn = t;
    
                            foreach (Setter set in retStyle.Setters)
                                newStyle.Setters.Add(new Setter() { Property = set.Property, Value = set.Value }); 
    
                            return newStyle;                                              
                        }
                    }
                }
            }
            return retStyle;
        }
        return null; 
    }
    
  3. 将主题绑定到样式,并在您使用的每个自定义样式上使用转换器

    Style =“{Binding Theme,Converter = {StaticResource styleConverter},ConverterParameter = {StaticResource ButtonStyle1}}”

  4. 其中theme是Theme(System.Windows.Controls.Theming)类型的属性。

    我上传了我的示例项目here 示例代码未更新,但您可以从那里开始。