【问题标题】:Adaptive Triggers in Resource Dictionary资源字典中的自适应触发器
【发布时间】:2017-03-05 21:36:10
【问题描述】:

我试图让页面的简单标题“自适应地”更改基于页面宽度的填充值。即我有一个标题 TextBlock 使用资源字典中的样式,如下所示:

<Style x:Key="PageHeaderStyle" TargetType="TextBlock">
        <Setter Property="FontSize" Value="16" />
        <Setter Property="VerticalAlignment" Value="Center" />
        <Setter Property="FontWeight" Value="Bold" />
</Style>

现在在我的页面中,我有一个简单的 TextBlock,它使用上面资源字典中的样式。在页面中,如果我使用以下代码,我的自适应触发器如下所示一切正常:

    <Page
...
        Style="{StaticResource PageStyle}">

        <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup>
                    <VisualState x:Name="Narrow">
                        <VisualState.StateTriggers>
                            <AdaptiveTrigger MinWindowWidth="0" />
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <Setter Target="PageHeader.Padding" Value="48,0,0,0" />
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="Compact">
                        <VisualState.StateTriggers>
                            <AdaptiveTrigger MinWindowWidth="720" />
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <Setter Target="PageHeader.Padding" Value="0,0,0,0" />
                        </VisualState.Setters>
                    </VisualState>
                    <VisualState x:Name="Wide">
                        <VisualState.StateTriggers>
                            <AdaptiveTrigger MinWindowWidth="1024"/>
                        </VisualState.StateTriggers>
                        <VisualState.Setters>
                            <Setter Target="PageHeader.Padding" Value="0,0,0,0" />
                        </VisualState.Setters>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>

            <Grid.RowDefinitions>
                <RowDefinition Height="{StaticResource GridHamburgerHeight}"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="14"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            <Border Background="{x:Bind Path=helper:CommonStyles.HamburgerPaneBackgroundColour}" Grid.Row="0" Grid.ColumnSpan="2"/>
            <TextBlock Style="{StaticResource PageHeaderStyle}" Grid.Column="1" Text="HOME"/>
        </Grid>
    </Page>

我的问题是,如何将 Adaptive VisualStateManager 片段移动到资源字典本身的 Style 对象中,以便我可以重新使用此标题样式及其“自适应性”,而不必在每个页面上粘贴 VisualStateManager .

谢谢!

【问题讨论】:

    标签: xaml uwp windows-10


    【解决方案1】:

    正如我所尝试的,无法更改页面的模板,似乎总是使用默认模板。因此,考虑到 VisualStateManager 必须在 Control 的根元素中 - source at MSDN:

    控件作者或应用程序开发人员使用 VisualStateManager.VisualStateGroups 附加属性将 VisualStateGroup 对象元素添加到 XAML 中控件模板定义的根元素。

    您可能必须创建自定义 UserControl 或扩展 Page 类 - 您可以在其中添加 VisualStateManager 而您不必重复一遍,只需使用该控件/页面。


    这是一个非常简单的例子,应该被扩展,但它会给你一个起点(你can check at Github的源代码。对于你的情况,我会创建一个TemplatedControl - 右键单击您在解决方案管理器中的项目,然后 Add->New Item,然后选择 Templated Control,我们将其命名为 AdaptiveTriggerControl , 这应该在 Themes 文件夹中创建一个 cs 文件和一个 Generic.xaml。打开 AdaptiveTriggerControl.cs 文件并修改它派生的类- 从Control 更改为ContentControl

    public sealed class AdaptiveTriggerControl : ContentControl
    

    Generic.xaml 中定义控件:

    <Style TargetType="local:AdaptiveTriggerControl" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:AdaptiveTriggerControl">
                    <Border x:Name="MyBorder"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                        <!--Background="{TemplateBinding Background}"-->
                        <VisualStateManager.VisualStateGroups>
                            <VisualStateGroup>
                                <VisualState x:Name="Narrow">
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger MinWindowWidth="0" />
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="MyBorder.Background" Value="Red"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="Compact">
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger MinWindowWidth="720" />
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="MyBorder.Background" Value="Green"/>
                                    </VisualState.Setters>
                                </VisualState>
                                <VisualState x:Name="Wide">
                                    <VisualState.StateTriggers>
                                        <AdaptiveTrigger MinWindowWidth="1024"/>
                                    </VisualState.StateTriggers>
                                    <VisualState.Setters>
                                        <Setter Target="MyBorder.Background" Value="Blue"/>
                                    </VisualState.Setters>
                                </VisualState>
                            </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <ContentPresenter Content="{TemplateBinding Content}"/>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    

    那么你可以像这样简单地使用它:

    <local:AdaptiveTriggerControl>
        <TextBlock Text="Content of your page"/>
    </local:AdaptiveTriggerControl>
    

    More information 关于 TemplatedControlsa sample of creating UserControl.

    【讨论】:

    • 感谢您的建议和快速回复!你有关于如何使用 UserControls 的好教程吗?我以前从未这样做过。
    • @sikhness 我在回答中提供了更多信息和示例。
    • 非常感谢!
    猜你喜欢
    • 2015-05-05
    • 2011-02-09
    • 2020-10-09
    • 2017-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多