将 UWP VisualStateManager 与变量一起使用

Using UWP VisualStateManager with varables

我可以使用 VisualStateManager 来更改控件的各个属性。像这样:

           <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState>
                    <VisualState.StateTriggers>
                        <!--small window-->
                        <AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="Control1.FontSize" Value="13"/>
                        <Setter Target="Control2.FontSize" Value="13"/>
                        <Setter Target="Control3.FontSize" Value="13"/>
                        <Setter Target="Control4.FontSize" Value="13"/>
                    </VisualState.Setters>
                </VisualState>
                <VisualState>
                    <VisualState.StateTriggers>
                        <!--large window-->
                        <AdaptiveTrigger MinWindowHeight="665" MinWindowWidth="1000"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="Control1.FontSize" Value="24"/>
                        <Setter Target="Control2.FontSize" Value="24"/>
                        <Setter Target="Control3.FontSize" Value="24"/>
                        <Setter Target="Control4.FontSize" Value="24"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

这行得通,但打字太多了!

是否可以使用 VisualStateManager 设置字体值,然后在 XAML 中引用此变量?

像这样:

          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>
                <VisualState>
                    <VisualState.StateTriggers>
                        <!--small window-->
                        <AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="@MyFontSize" Value="13"/>
                    </VisualState.Setters>
                </VisualState>
                <VisualState>
                    <VisualState.StateTriggers>
                        <!--large window-->
                        <AdaptiveTrigger MinWindowHeight="665" MinWindowWidth="1000"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="@MyFontSize" Value="24"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

然后我可以在设计控件时在 XAML 中使用 @MyFontSize 变量,我可以在一个地方更改它。

<TextBlock x:Name="Control1" FontSize="@MyFontSize"/>
<TextBlock x:Name="Control2" FontSize="@MyFontSize"/>
<TextBlock x:Name="Control3" FontSize="@MyFontSize"/>

是否可以使用 UWP VisualStateManager 做这样的事情?

Is it possible to use VisualStateManager to set a value for the font and than refer to this variable in XAML

恐怕您无法在 VisualStateManager 内设置变量,但对于您的情况,我们有一个解决方法,即使用 Setting class 作为媒介并影响其他 TextControl MVVM 绑定。

例如

public class Setting : INotifyPropertyChanged
{
    private double _fontSize = 10;
    public double CFontSize
    {
        get { return _fontSize; }
        set { _fontSize = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

用法

<Page.Resources>
    <local:Setting x:Key="Setting" />
</Page.Resources>
<StackPanel>
    <TextBlock
        x:Name="BaseControl"
        VerticalAlignment="Center"
        FontSize="{Binding CFontSize, Source={StaticResource Setting}, Mode=TwoWay}"
        Text="Hello" />
    <TextBlock
        x:Name="Control1"
        VerticalAlignment="Center"
        FontSize="{Binding CFontSize, Source={StaticResource Setting}, Mode=TwoWay}"
        Text="How are you" />
    <TextBlock
        x:Name="Control2"
        VerticalAlignment="Center"
        FontSize="{Binding CFontSize, Source={StaticResource Setting}, Mode=TwoWay}"
        Text="Fine thank you, and you?" />

    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup>
            <VisualState>
                <VisualState.StateTriggers>
                    <!--  small window  -->
                    <AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="BaseControl.FontSize" Value="13" />
                </VisualState.Setters>
            </VisualState>
            <VisualState>
                <VisualState.StateTriggers>
                    <!--  large window  -->
                    <AdaptiveTrigger MinWindowHeight="665" MinWindowWidth="1000" />
                </VisualState.StateTriggers>
                <VisualState.Setters>
                    <Setter Target="BaseControl.FontSize" Value="24" />
                </VisualState.Setters>
            </VisualState>
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</StackPanel>

受@Nico Zhu 的启发,找到了一种类似但更简单的方法。在这里分享以防其他人觉得有用。

我的方法是使用一个控件作为模板并将该类型的所有其他控件绑定到它。

VisualStateManager 设置“主”控件的 属性:

  <VisualStateManager.VisualStateGroups>
            <VisualStateGroup>

                <VisualState>
                    <VisualState.StateTriggers>
                        <!--VisualState to be triggered when window width is <665 effective pixels.-->

                        <AdaptiveTrigger MinWindowHeight="0" MinWindowWidth="0"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="txtHeader.FontSize" Value="13"/>
                        <Setter Target="txtRegular.FontSize" Value="10"/>
                    </VisualState.Setters>
                </VisualState>
                <VisualState>
                    <VisualState.StateTriggers>
                        <AdaptiveTrigger MinWindowHeight="665" MinWindowWidth="1000"/>
                    </VisualState.StateTriggers>
                    <VisualState.Setters>
                        <Setter Target="txtHeader.FontSize" Value="20"/>
                        <Setter Target="txtRegular.FontSize" Value="16"/>
                    </VisualState.Setters>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>

所有其他控件都可以绑定到“主”控件。

<TextBlock Text="My Header 1" FontSize="{Binding ElementName=txtHeader, Path=FontSize}" />
<TextBlock Text="My Header 2" FontSize="{Binding ElementName=txtHeader, Path=FontSize}" />
<TextBlock Text="My regular text 1" FontSize="{Binding ElementName=txtRegular, Path=FontSize}" />
<TextBlock Text="My regular text 2" FontSize="{Binding ElementName=txtRegular, Path=FontSize}" />

当用户调整页面大小时,VisualStateManager 将更改主控件,所有其他控件将通过绑定获得。

如果需要,您可以创建隐藏控件作为模板服务器。