locked
Changing ResourceDictionary at runtime.

    Question

  • Hello!

    I have a very common situation.

    I wish to create a different styles for my application. So, I add one style in XAML code, and in runtime I remove it and adding new:

    App.Current.Resources.MergedDictionaries.Remove(App.Current.Resources.MergedDictionaries.Last());
    
    ResourceDictionary dict = new ResourceDictionary();
    dict.Source = new Uri("ms-appx:AppStyle2.xaml");
    Application.Current.Resources.MergedDictionaries.Add(dict);

    But interface is not refreshed..

    I have seeing a topic where answer was that app resources are frosen, so I have add resourses to my UserControl, but even when I change in code behind resourcedictionary interface isn't refreshed.

      ResourceDictionary cd = new ResourceDictionary();
      cd = this.Resources.MergedDictionaries.ElementAt(0);
      this.Resources.MergedDictionaries.Remove(cd);
      cd.Source = new Uri("ms-appx:CharmStyle1.xaml");
      this.Resources.MergedDictionaries.Add(cd);

    Wednesday, January 07, 2015 9:28 AM

Answers

All replies

  • Hi,

    I create a project to test the problem. It seems to the ThemeResource or StaticResource cannot be updated when use the different ResourceDictionary. You can update the control's style resource after you changed the ResourceDictionary, then you can see the control's style can refreshed.

    See some codes below:

     <Page.Resources>
            <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Assets/Dictionary2.xaml"></ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
        </Page.Resources>
        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
            <Button Content="Button" HorizontalAlignment="Left" Margin="613,254,0,0" VerticalAlignment="Top" Height="53" Background="{ThemeResource fadeBrush}" x:Name="btn1" />
            <Button Content="Button" HorizontalAlignment="Left" Margin="920,346,0,0" VerticalAlignment="Top" Click="Button_Click"/>
    
        </Grid>
      private void Button_Click(object sender, RoutedEventArgs e)
            {
                
                this.Resources.MergedDictionaries.Remove(this.Resources.MergedDictionaries.ElementAt(0));
                ResourceDictionary dict = new ResourceDictionary();
                dict.Source = new Uri("ms-appx:///Assets/Dictionary1.xaml", UriKind.RelativeOrAbsolute);
                this.Resources.MergedDictionaries.Add(dict);
                btn1.Background = Resources["fadeBrush"] as LinearGradientBrush;//update the button style
             
            }

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. <br/> Click <a href="http://support.microsoft.com/common/survey.aspx?showpage=1&scid=sw%3Ben%3B3559&theme=tech"> HERE</a> to participate the survey.

    Thursday, January 08, 2015 6:53 AM
  • Thank you, Anne!

    But this is what I have exactly did before also with app resources.

    I have hoping that there are any way to refresh all page elements without imperatively refreshing every element.

    Something like Page.Refresh() and all elements of page are updating there styles.

    I have tried 

    ResourceManager.Current.DefaultContext.Reset();

    and even

     Windows.ApplicationModel.Resources.Core.ResourceContext.GetForCurrentView().Reset();

    but without success

    Thursday, January 08, 2015 8:05 AM
  • I am afraid that the there is no event raised to the layout system when you clear and add a new ResourceDictionary like this.

    The solution seems to be bind to source properties of a view model that returns the resources to be used and have the view model class implement the INotifyPropertyChanged as usual (don't shoot the messenger). Please refer to the following thread for more information: https://social.msdn.microsoft.com/Forums/windowsapps/en-US/7de32e00-7456-4b7c-9926-688920ca88bf/dynamically-change-theme-switch-resource-dictionaries-in-runtime?forum=winappswithcsharp

    Please remember to mark helpful posts as answer and/or helpful.

    Thursday, January 08, 2015 3:40 PM
  • Thank you!
    I have afraid that it is not posible.
    In this case I will better refresh all elements manualy. It is looks more simple that write INotifyPropertyChanged for every element.


    Thursday, January 08, 2015 5:11 PM
  • Have found in MVA tutorial snippet:

    var t = new ResourceDictionary{ Source=themeURL };
    var r = new ResourceDictionary{ MergedDictionaries ={ t } };
    App.Current.Resources = r;
    
    this.Frame.Navigate(this.GetType());
    this.Frame.GoBack();

    Saturday, March 07, 2015 8:34 AM