AdaptiveTrigger и 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>

2 ответа

Решение

Попробуйте обернуть DataTemplate внутри UserControl как это -

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

Выглядит как любой Control который получил Content собственность будет работать. Вот почему 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

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()));

}
Другие вопросы по тегам