可以在 VisualStateManager 中修改静态资源吗?

Fer*_*hen 5 c# uwp

我有许多用于字体大小、画笔等的全局常量。示例:

<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>
Run Code Online (Sandbox Code Playgroud)

当窗口宽度变小时,我想减少一些文本的字体大小。当然,我可以单独针对它们中的每一个,但我宁愿做的是全局更改 {StaticResource NormalFontSize},如下所示:

<VisualState x:Name="Small">
                <VisualState.StateTriggers>
                    <AdaptiveTrigger MinWindowWidth="{StaticResource SmallWindowWidth}" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="{StaticResource NormalFontSize}" Value="12"/>
                </VisualState.Setters>
            </VisualState>
Run Code Online (Sandbox Code Playgroud)

...这似乎不起作用,因为它不是财产。那么,有没有办法更改 XAML (!) 中的静态资源?

Ahm*_*med 2

嗯,你可以通过一些调整来做到这一点。请注意,我已在 UWP 中进行了本地测试来回答您的问题,但我尚未在任何已发布的项目中使用它。

第一步,

  • 如果您需要更改具有依赖属性的资源,例如实心画笔的颜色。[无需包装]
  • 如果您需要更改没有依赖属性(例如双精度值)的资源[需要包装器]

    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));
    
    }
    
    Run Code Online (Sandbox Code Playgroud)

第二步,除了强制的 x:Key 之外,您还需要定义 x:Name 以便能够在视觉状态设置器中定位静态资源。(如果需要,您可以为 x:Name 使用不同的名称)

    <Page.Resources>
      <local:DoubleWrapper x:Name="FontSizeWrapper" x:Key="FontSizeWrapper" Value="12"/>
      <SolidColorBrush x:Name="MainBrush" x:Key="MainBrush" Color="Red"/>
    </Page.Resources>
Run Code Online (Sandbox Code Playgroud)

最后,当您在 Visual state setter 中更改 FontSizeWrapper 或 MainBrush 的 Value 属性时,它将更新所有绑定。

<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>
Run Code Online (Sandbox Code Playgroud)