【问题标题】:Using UWP VisualStateManager with varables将 UWP VisualStateManager 与变量一起使用
【发布时间】:2021-01-08 05:28:47
【问题描述】:

我可以使用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 做类似的事情?

【问题讨论】:

    标签: xaml uwp visualstatemanager


    【解决方案1】:

    是否可以使用 VisualStateManager 为字体设置一个值,而不是在 XAML 中引用这个变量

    恐怕你不能在VisualStateManager 中设置变量,但是对于你的场景,我们有一个解决方法,使用Setting 类作为媒介并影响其他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>
    

    【讨论】:

    • 绝招!因此,您使用 VisualSateManager 为一个控件设置属性,而所有其他控件都继承自它。谢谢!
    【解决方案2】:

    在@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 将更改主控件,所有其他人将通过绑定获得它。

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-06-08
      • 1970-01-01
      • 2014-09-05
      • 2011-09-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多