资源字典中的自适应触发器

时间:2017-03-05 21:36:11

标签: xaml uwp windows-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,它使用上面资源字典中的Style。在页面中,如果我使用以下代码,我的自适应触发器如下所示,一切正常:

    <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对象中,以便我可以重新使用此标题样式及其“adaptive-ness”,而无需在每个页面上粘贴VisualStateManager

谢谢!

1 个答案:

答案 0 :(得分:1)

由于我已经尝试过无法更改网页模板,因此似乎总是使用默认模板。因此,考虑到 VisualStateManager 必须位于 Control 的根元素中 - source at MSDN

  

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

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

这是一个非常简单的示例,应该进行扩展,但它会给你一个启动点(源代码为can check at Github。对于你的情况,我会创建一个 TemplatedControl - 对在解决方案管理器中单击您的项目,然后添加 - &gt; New Item ,然后选择模板化控件,让它命名为 AdaptiveTriggerControl < / em>,这应该在 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关于 TemplatedControls a sample of creating UserControl