Jan 042013
 
 January 4, 2013  Posted by at 2:20 pm WinRT  Add comments

I’ve noticed that the last how to change style during runtime example I posted is rather popular, and earlier today I was trying to help somebody with a TextBlock style change implementation for a Windows Store App. The difference this time was that we wanted to change an existing style, not just switch styles. Wether or not that is a good idea is a discussion on its own (and depends on the scenario).

change style at runtime

change style at runtime2

Nontheless, here is a quick sample for a MVVM friendly implementation for how to change an existing style resource (defined in a resource dictionary) at runtime.

View:

[sourcecode language=”XML”]
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<ListBox ItemsSource="{Binding Fonts}" Height="300" Width="300" SelectionChanged="ListBox_SelectionChanged_1"></ListBox>
<Border BorderBrush="White" BorderThickness="5" Padding="20,0,0,0" Height="300" Width="500">
<TextBlock x:Name="test" Text="Hi here is some text" Style="{Binding FontStyleText}"/>
</Border>
</StackPanel>
[/sourcecode]

The style defined at /Common/StandardStyles.xaml

[sourcecode language=”XML”]
<Style x:Key="textStyle" TargetType="TextBlock">
<Setter Property="Foreground" Value="red"/>
<Setter Property="FontFamily" Value="Segoe UI"/>
<Setter Property="FontSize" Value="35"/>
</Style>
[/sourcecode]

The code:

[sourcecode language=”csharp”]
public sealed partial class MainPage : INotifyPropertyChanged
{
private Style _fontStyleText;
public Style FontStyleText
{
get { return this._fontStyleText; }

set
{
if (value == this._fontStyleText) return;
this._fontStyleText = value;
NotifyPropertyChanged();
}
}

private List<string> _fonts;
public List<string> Fonts
{
get { return this._fonts; }

set
{
if (value == this._fonts) return;
this._fonts = value;
NotifyPropertyChanged();
}
}

public MainPage()
{
this.InitializeComponent();
DataContext = this;

Fonts = new List<string> {"Segoe UI", "Showcard Gothic", "Arial"};

FontStyleText = Application.Current.Resources["textStyle"] as Style;

}

private void ListBox_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
{
var font = (sender as ListBox).SelectedItem as string;

var res = new ResourceDictionary { Source = new Uri("ms-appx:///Common/StandardStyles.xaml", UriKind.Absolute)};

var style = res["textStyle"] as Style;

style.Setters.RemoveAt(0); // if it is the first item otherwise for more accurat removal se below

foreach (var item in style.Setters.Cast<Setter>().Where(item => item.Property == FontFamilyProperty))
style.Setters.Remove(item);

style.Setters.Add(new Setter(TextBlock.FontFamilyProperty, new FontFamily(font)));
style.Setters.Add(new Setter(TextBlock.ForegroundProperty, new SolidColorBrush(Colors.Yellow)));

FontStyleText = style;
}

public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged([CallerMemberName] String propertyName = "")
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
[/sourcecode]

  3 Responses to “Example WinRT: Changing existing style resource at runtime in code using databindings”

  1. Hello,
    your sample works well, but in Win8.1, when I try to debug it, there is no item which match the request in the foreach. Furthermore, there is 2 FontFamily setter in the style after the changes…
    Is there another way to compare the setter object ?
    Regards
    Thierry

    • Hi Thierry! Let me have a look at this tomorrow and I’ll try to sort it out. I have to admit I haven’t used the code in Win8.1 – but how annoying behavior is changed! Will ping you once I figure it out, unless you beat me to it 😉

      • Hi Iris !,
        I finally found the problem… in fact, the only missing thing is the TextBlock prefix on the where clause like :
        Where (item => item.Property == TextBlock.FontFamilyProperty)
        Now it works well and there is only one FontFamily in the Setter collection.

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

What is 10 + 7 ?
Please leave these two fields as-is:
IMPORTANT! To be able to proceed, you need to solve the following simple math (so we know that you are a human) :-)