开发者

How can I base a style on a Silverlight toolkit theme?

is it possible to do this?

In my xaml code, I have some ComboBoxes with a style, defined like this:

<Style x:Key="comboProjectsStyle"
       TargetType="ComboBox">
    <Setter Property="ItemTemplate">
        <Setter.Value>
          开发者_Go百科  <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}" />

The silverlight theme (eg: ExpressionDark) is correctly applied on every controls except on the ones where I have defined a style, like above.

As I understand, in WPF we could use x:Style an base our Style on the silverlight theme using the "BasedOn" property. However, it seems like it is not possible to do so with Silverlight 4.

Any ideas on how to approach this?

Thanks!


Declare your ItemTemplate as a resource rather than in a style then your theme style will apply.

<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>


Remove the key in the style:

    <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" />

Basically this means the style you made above applies to a target type of ComboBox, it is not named therefore every Combobox without a style set to it will inherit this as default.

UPDATE: As you can see all the 3 styles can coexist in the same resource, whenever you use a named style it will be applied to the said control but, for the last three comboboxes, all 3 will be having the style without the key. This is how it is done in themming, like in the JetPack skin from MS.

hope this helps.


Hi this is not exactly using basedOn but by using a converter we can achieve the goal of basing the custom style to the theme. Here's how we do it.

  1. Expose a Theme and place it where you can bind it to the style.

  2. Create a value converter to convert the style that you are using. This converter will return a style that is based on the theme, so here's a snippet.

    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. Bind the theme to the style and use the converter on every custom style that you use

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

Where theme is a property of type Theme(System.Windows.Controls.Theming).

I uplaoded my sample project here The sample code is not updated but you can start from there.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜