自适应触发器和数据模板

AdaptiveTrigger and DataTemplate

AdaptiveTrigger 可以在 DataTemplate 中工作吗?

那是我用来自定义 ShellNavigation 的代码,它工作正常,但视觉状态除外。他们不会触发任何东西。

<shell:ShellHeadView x:Key="ShellHeadView_01">
    <shell:ShellHeadView.ContentTemplate>
        <DataTemplate>
            <Grid Margin="20,0">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup>
                        <VisualState x:Name="GreenBackgroundVisualState">
                            <VisualState.Setters>
                                <Setter Target="headViewLeft.Background" Value="Green" />
                            </VisualState.Setters>
                            <VisualState.StateTriggers>
                                <AdaptiveTrigger MinWindowWidth="1000"/>
                            </VisualState.StateTriggers>
                        </VisualState>
                        <VisualState x:Name="OrangeBackgroundVisualState">
                            <VisualState.Setters>
                                <Setter Target="headViewLeft.Background" Value="Orange" />
                            </VisualState.Setters>
                            <VisualState.StateTriggers>
                                <AdaptiveTrigger MinWindowWidth="2000"/>
                            </VisualState.StateTriggers>
                        </VisualState>
                        <VisualState x:Name="RedBackgroundVisualState">
                            <VisualState.Setters>
                                <Setter Target="headViewLeft.Background" Value="Red" />
                            </VisualState.Setters>
                            <VisualState.StateTriggers>
                                <AdaptiveTrigger MinWindowWidth="3000"/>
                            </VisualState.StateTriggers>
                        </VisualState>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <Grid Grid.Column="0" x:Name="headViewLeft" Width="100" Height="90">

                </Grid>

尝试像这样将 DataTemplate 包裹在 UserControl 中 -

<DataTemplate>
    <UserControl>
        <Grid>
            <VisualStateManager.VisualStateGroups>
            ...
        </Grid>
    </UserControl>
</DataTemplate>

看起来任何具有 Content 属性 的 Control 都可以使用。这就是 UserControl 有效的原因,ContentControl.

也是如此

因此,如果您将 UserControl 替换为 ContentControl 并将其设为空 Style。它也应该有效。

<Style x:Key="EmptyContentControlStyle" TargetType="ContentControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ContentControl" />
        </Setter.Value>
    </Setter>
</Style>

<DataTemplate>
    <ContentControl Style="{StaticResource EmptyContentControlStyle}">
        <Grid>
            <VisualStateManager.VisualStateGroups>
            ...
        </Grid>
    </ContentControl>
</DataTemplate>

创建两个数据模板。使用自适应触发器更改 ItemsControl

上的 ItemTemplate

TBH 将自适应触发器放在通用模板中而不是页面视图中对我来说感觉有点奇怪。

一般来说,我会强烈建议不要像另一个答案中建议的那样将用户控件放在数据模板中。用户控件很慢,因此将它们放在反复使用的模板中可能会影响性能(带有控件模板的自定义控件是更好的选择)。

您还可以创建一个在模板之间切换的自定义控件。示例:

public class AdaptiveControl : ContentControl
{
    public AdaptiveControl()
    {
        SizeChanged += AdaptiveControl_SizeChanged;
    }

    private void AdaptiveControl_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        Update();
    }
    private void Update() 
    {
        if (ActualWidth < Size)
            ContentTemplate = SmallTemplate;
        else
            ContentTemplate = LargeTemplate;
    }

    public double Size
    {
        get { return (double)GetValue(SizeProperty); }
        set { SetValue(SizeProperty, value); }
    }

    public static readonly DependencyProperty SizeProperty =
        DependencyProperty.Register(nameof(Size), typeof(double), typeof(AdaptiveControl), new PropertyMetadata(200d, (s, e) => ((AdaptiveControl)s).Update()));

    public DataTemplate SmallTemplate
    {
        get { return (DataTemplate)GetValue(SmallTemplateProperty); }
        set { SetValue(SmallTemplateProperty, value); }
    }

    public static readonly DependencyProperty SmallTemplateProperty =
        DependencyProperty.Register(nameof(SmallTemplate), typeof(DataTemplate), typeof(AdaptiveControl), new PropertyMetadata(null, (s, e) => ((AdaptiveControl)s).Update()));


    public DataTemplate LargeTemplate
    {
        get { return (DataTemplate)GetValue(LargeTemplateProperty); }
        set { SetValue(LargeTemplateProperty, value); }
    }

    public static readonly DependencyProperty LargeTemplateProperty =
        DependencyProperty.Register(nameof(LargeTemplate), typeof(DataTemplate), typeof(AdaptiveControl), new PropertyMetadata(null, (s, e) => ((AdaptiveControl)s).Update()));

}