Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can static resources be modified in a VisualStateManager?

Tags:

c#

uwp

I have a number of global constants for font sizes, brushes, etc. Examples:

<x:Double x:Key="SmallWindowWidth">0</x:Double>
<x:Double x:Key="CompactWindowWidth">600</x:Double>
<x:Double x:Key="MediumWindowWidth">720</x:Double>
<x:Double x:Key="WideWindowWidth">1024</x:Double>

<x:Double x:Key="SmallTitleFontSize">22</x:Double>
<x:Double x:Key="NormalFontSize">16</x:Double>

When the Window Width becomes small I would like to reduce the FontSize of some texts. Of course I could target each and every single one of them individually, but what I would rather do is globally change the {StaticResource NormalFontSize}, like this:

<VisualState x:Name="Small">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="{StaticResource SmallWindowWidth}" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="{StaticResource NormalFontSize}" Value="12"/>
                </VisualState.Setters>
            </VisualState>

...which doesn't seem to work as it is no property. So, is there any way to change static resources in XAML (!)?

like image 906
Ferdinand von den Eichen Avatar asked Oct 31 '22 15:10

Ferdinand von den Eichen


1 Answers

Well, You can do it with some tweaks. Note, I have locally tested it in UWP to answer your question but I didn't use it in any of my published projects yet.

First Step,

  • If you need to change a resource that has dependency property, like color of solid brush.[No Wrapper needed]
  • If you need to change a resource that doesn't have dependency property like double value [Wrapper Needed]

    public class DoubleWrapper : DependencyObject
    {
       public double Value
        {
          get { return (double)GetValue(ValueProperty); }
          set { SetValue(ValueProperty, value); }
        }
    
    // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(double), typeof(DoubleWrapper), new PropertyMetadata(0.0));
    
    }
    

Second Step, You need to define x:Name besides the mandatory x:Key To be able to target a static resource in visual state setter. (you can use different name for x:Name, if you want)

    <Page.Resources>
      <local:DoubleWrapper x:Name="FontSizeWrapper" x:Key="FontSizeWrapper" Value="12"/>
      <SolidColorBrush x:Name="MainBrush" x:Key="MainBrush" Color="Red"/>
    </Page.Resources>

Finally, when you change Value property of FontSizeWrapper or MainBrush in Visual state setter, it will update all bindings.

<Grid>
        <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="LayoutStates">
            <VisualState x:Name="NarrowState">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="0"/>
                </VisualState.StateTriggers>
                <VisualState.Setters>
                </VisualState.Setters>
            </VisualState>
            <VisualState x:Name="WideState">
                <VisualState.Setters>
                    <Setter Target="FontSizeWrapper.(DoubleWrapper.Value)" >
                        <Setter.Value>
                            <x:Double>25</x:Double>
                        </Setter.Value>
                    </Setter>
                    <Setter Target="MainBrush.(SolidColorBrush.Color)" Value="Aqua" />
                </VisualState.Setters>
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="800"/>
                </VisualState.StateTriggers>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <TextBlock Text="This is test" Foreground="{StaticResource MainBrush}"
               VerticalAlignment="Center"  
               FontSize="{Binding Value, Source={StaticResource FontSizeWrapper}}"/>
 </Grid>
like image 121
Ahmed Rashad Mohamed Avatar answered Nov 13 '22 01:11

Ahmed Rashad Mohamed