Наличие одного триггера данных для нескольких элементов управления

#.net #wpf #xaml #datatrigger

#.net #wpf #xaml #datatrigger

Вопрос:

Я хочу иметь один стиль DataTrigger внутри моего window.ресурсы, которые можно использовать для нескольких расширителей. DataTrigger привязан к значению enum внутри моей ViewModel, и на основе значения enum я хочу, чтобы правильные расширители были свернуты. Например: если для значения enum установлено значение «A», то я хочу, чтобы был виден только расширитель, связанный с типом «A», а остальные расширители были свернуты.

Я думал о чем-то подобном:

     <Style TargetType="{x:Type Expander}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Type}" Value="A">
                // In here i would set the expander associated w/ "A" to Visible 
                // and have the rest of the expanders collapsed. Since TargetName is 
                // not allowed within a "Setter" property of a style, I am not sure on how to accomplish this.
            </DataTrigger>
            <DataTrigger Binding="{Binding Type}" Value="B">
               // Same concept as above
            </DataTrigger>
        </Style.Triggers>
    </Style>
  

Комментарии:

1. У кого-то может быть ответ для вас, но я не думаю, что XAML будет поддерживать этот уровень логики. Это скорее прямой переход к экранной инструкции. Если значение Enum задается с помощью элемента управления пользовательского интерфейса, вы можете сделать это с помощью обработчика событий или установить триггеры для отдельных расширителей.

Ответ №1:

Я полагаю, что вы сможете вручную настроить стили для каждого конкретного класса расширителя, чтобы избежать дублирования кода триггера, вы можете использовать Style .На основе построения иерархии зависимых стилей:

  <Style x:key=ExpanderBaseStyle" TargetType="{x:Type Expander}">
   <!-- trigger logic -->
 </Style>

 <Style TargetType="{x:Type FirstExpander}" 
                     BasedOn="{StaticResource ExpanderBaseStyle}"/>

 <Style TargetType="{x:Type SecondExpander}" 
                     BasedOn="{StaticResource ExpanderBaseStyle}"/>
  

Комментарии:

1. Я собираюсь попробовать это и посмотреть, сработает ли это. Спасибо за помощь.

2. Я не смог заставить это работать. мне нужно одно значение enum (в моей viewmodel), чтобы установить видимость 3 элементов управления. Я смог сделать это, прослушав событие propertychanged внутри моей viewmodel из его кода, а затем соответствующим образом настроив элементы управления, но не был уверен, существует ли прямое решение xaml.

3. Спасибо, что указали мне правильное направление. Я смог решить эту проблему с помощью решения, которое я опубликовал.

Ответ №2:

Я смог решить эту проблему (используя несколько триггеров) со статическим ресурсом, который приводил к «сворачиванию» каждого элемента управления, а затем имел отдельные «DataTriggers» внутри каждого элемента управления, где соответствующее значение enum делает видимость «видимой».

Смотрите ниже (в этом примере я использовал canvas):

    <Grid>
    <Grid.Resources>          
        <Style x:Key="CanvasStyle">
            <Setter Property="Canvas.Visibility" Value="Collapsed"/>
        </Style>
    </Grid.Resources>
    <ComboBox IsSynchronizedWithCurrentItem="True" Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="153" ItemsSource="{Binding IDs}" MaxDropDownHeight="75" SelectedValue="{Binding SelectedValue}"/>
    <StackPanel Height="128" HorizontalAlignment="Left" Orientation="Horizontal">
        <Canvas Height="100" Name="canvas1" Width="100" Background="#FFC70D0D">
            <Canvas.Style>
                <Style BasedOn="{StaticResource CanvasStyle}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Type}" Value="A">
                            <Setter Property="Canvas.Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Canvas.Style>
        </Canvas>
        <Canvas Background="#FF63C70D" Height="100" Name="canvas2" Width="100">
            <Canvas.Style>
                <Style BasedOn="{StaticResource CanvasStyle}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Type}" Value="B">
                            <Setter Property="Canvas.Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Canvas.Style>
        </Canvas>
        <Canvas Background="#FF0D55C7" Height="100" Name="canvas3" Width="100">
            <Canvas.Style>
                <Style BasedOn="{StaticResource CanvasStyle}">
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding Type}" Value="C">
                            <Setter Property="Canvas.Visibility" Value="Visible" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </Canvas.Style>
        </Canvas>
    </StackPanel>
</Grid>