How to easily allow users to update Styles used be

2019-01-26 01:52发布

问题:

This is for a Windows 10 UWP. I need to allow users to update values on Styles that are associated with elements used throughout the application (i.e allow users to change the font size of various textblocks, background color stackpanels etc.) .

I currently have all my Styles in a separately file.

My App.xaml is as below:

<Application
    x:Class="MyTestApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Application.Resources>

        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="/Styles/Styles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>

    </Application.Resources>

</Application>

My Styles.xaml (partial) is as below:

<ResourceDictionary
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:converters="using:MyTestApp.Views"
    xmlns:x1="using:System">

    <Style x:Key="HeaderTextBlocks" TargetType="TextBlock" BasedOn="{StaticResource TitleTextBlockStyle}">
        <Setter Property="FontSize" Value="24"/>
        <Setter Property="FontWeight" Value="Normal"/>
        <Setter Property="TextWrapping" Value="NoWrap"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Bottom"/>
        <Setter Property="Margin" Value="10,4,0,0"/>
    </Style>

    <Style x:Key="RegularTextBlocks" TargetType="TextBlock" BasedOn="{StaticResource TitleTextBlockStyle}">
        <Setter Property="FontSize" Value="12"/>
        <Setter Property="FontWeight" Value="Normal"/>
        <Setter Property="TextWrapping" Value="NoWrap"/>
        <Setter Property="HorizontalAlignment" Value="Left"/>
        <Setter Property="VerticalAlignment" Value="Bottom"/>
        <Setter Property="Margin" Value="0,0,0,0"/>
    </Style>
</ResourceDictionary>

I refer to these styles on controls throughout the application using like this:

<TextBlock Style="{StaticResource HeaderTextBlocks}" />

I have created a Settings page (settings.xaml) which has textboxes for the users to update various style settings.

But I am not sure how I could bind these to the settings on the various styles on the styles.xaml file so that the styles are updated and the controls referring to the styles are updated when the user changes the value.

<TextBox Header="Font Size of Header TextBlocks" Text="{x:Bind HeaderTextBlocks.FontSize ???, Mode=TwoWay}" />
<TextBox Header="Font Size of Regular TextBlocks" Text="{x:Bind RegularTextBlocks.FontSize???, Mode=TwoWay}" />

Could someone please point me in the right direction? I am trying to do this with minimal (or no code behind) as possible.

回答1:

Unfortunately this kind of user-defined styling is not easily available in UWP. You can however implement a kind of styling solution using data binding.

First step is to create a class like CustomUISettings which implements INotifyPropertyChanged and has properties like HeaderFontSize, etc.

Now on app start create an instance of this class and add it as app resource:

Application.Current.Resources["CustomUISettings"] = new CustomUISettings();

Now you can bind to the properties in this class anywhere in your code:

<TextBox FontSize="{Binding HeaderFontSize, Source={StaticResource CustomUISettings}}" />

You must use the classic {Binding} markup extension, because {x:Bind} does not support Source setting.

To modify the UI settings you can just retrieve the instance anywhere and set the properties as you see fit:

var customUISettings = (CustomUISettings)Application.Current.Resources["CustomUISettings"];
customUISettings.HeaderFontSize = 50;

You must make sure that all properties in CustomUISettings class fire the PropertyChanged event. You can see how to implement INotifyPropertyChanged interface for example here.