Josh Close
Josh Close

Reputation: 23393

Apply global theme changes immediately

I my WinRT app the user can sync their data with a server. Some of the data that is synced are global theme changes for the application.

I go about changing the global theme by dynamically creating a XAML file, then doing this.

var resource = (ResourceDictionary)XamlReader.Load( content );

I then overwrite the global themes for the app by doing this.

var resources = new ResourceDictionary();
var converters = new ResourceDictionary { Source = new Uri( "ms-appx:/Resources/Converters.xaml" ) };
var callisto = new ResourceDictionary { Source = new Uri( "ms-appx:/Resources/Callisto.xaml" ) };
var templates = new ResourceDictionary { Source = new Uri( "ms-appx:/Resources/Templates.xaml" ) };

resources.MergedDictionaries.Add( converters );
resources.MergedDictionaries.Add( callisto );
resources.MergedDictionaries.Add( templates );
resources.MergedDictionaries.Add( resource );

App.Current.Resources = resources;

The resource file has this.

<ImageBrush x:Key="ApplicationPageBackgroundThemeImageBrush" ImageSource="%%ThemeBackground%%" Stretch="UniformToFill" />

The %%ThemeBackground%% is replaced with the actual file location.

Some of the changes apply immediately, like the NavigationBackButtonNormalStyle style, but others do not, like an ImageBrush. The changes only show when the app is started again, and this code is ran during application launch in App.xaml.cs, instead of from a running page.

It this even possible?

Some notes on how this works.

Update

I also have a sort of "Master Page" setup with this. This is how it's created.

var currentFrame = (Frame)Window.Current.Content;
var masterPage = new MasterPage
{
    ContentFrame = currentFrame,
};
Window.Current.Content = masterPage;

The master page just contains the TopAppBar.

<Page.TopAppBar>
    <!-- buttons here -->
</Page.TopAppBar>
<Grid>
    <ContentControl Content="{Binding ContentFrame, ElementName=PageRoot}" />
</Grid>

The background image that isn't updating is applied like this on every page.

<Border Background="{ThemeResource ApplicationPageBackgroundThemeImageBrush}"></Border>

Upvotes: 1

Views: 127

Answers (1)

Jerry Nixon
Jerry Nixon

Reputation: 31831

Just reload the page.

You can try this:

public bool Reload(object param = null)
{
    Type type = this.Frame.CurrentSourcePageType;
    if (this.Frame.BackStack.Any())
    {
        type = this.Frame.BackStack.Last().SourcePageType;
        param = this.Frame.BackStack.Last().Parameter;
    }
    try { return this.Frame.Navigate(type, param); }
    finally { this.Frame.BackStack.Remove(this.Frame.BackStack.Last()); }
}

Best of luck!

Upvotes: 1

Related Questions