Члены коллекции триггеров должны иметь тип EventTrigger - PullRequest
24 голосов
/ 07 мая 2009

Я создал UserControl, похожий на следующий:

<UserControl>
    <StackPanel Orientation="Vertical">

        <StackPanel x:Name="Launch" Orientation="Horizontal" Visibility="Collapsed">
            <!-- Children here -->
        </StackPanel>

        <ToggleButton x:Name="ToggleLaunch" IsChecked="False" Content="Launch" />

    </StackPanel>
</UserControl>

Я пытался использовать DataTrigger, чтобы StackPanel 'Launch' стал видимым, когда отмечена кнопка ToggleButton, и остался свернутым в противном случае. Однако во время выполнения я получаю сообщение об ошибке «Ошибка инициализации объекта (ISupportInitialize.EndInit). Члены коллекции триггеров должны иметь тип EventTrigger». Я попытался добавить его в коллекцию триггеров UserControl и StackPanel, но безуспешно. Мой триггер XAML выглядит следующим образом:

<DataTrigger Binding="{Binding ElementName=ToggleLaunch, Path=IsChecked}" Value="True">
    <Setter TargetName="Launch" Property="UIElement.Visibility" Value="Visible" />
</DataTrigger>

Ответы [ 4 ]

36 голосов
/ 20 сентября 2014

Из Документы MSDN , согласно (слегка перефразированному) ответу Ричарда К. Макгуайра:

DataTriggers можно использовать с тегами XML Стиль , ControlTemplate и DataTemplate

Например, если вы попытаетесь добавить триггер к TextBlock, он выдаст следующую ошибку:

Ошибка: члены коллекции триггеров должны иметь тип EventTrigger

Почему? Trigger может быть размещен только внутри Style, ControlTemplate или DataTemplate, и мы пытаемся разместить его непосредственно внутри TextBlock.

В этом случае исправить несложно: просто оберните триггер в стиле , затем поместите этот стиль в TextBlock, и ошибка исчезнет.

Вот XAML, генерирующий ошибки перед исправлением:

<TextBlock x:Name="Hello" Text="{Binding Hello, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
  <TextBlock.Triggers>
      <DataTrigger Binding="{Binding Hello}" Value="GoGreen">
          <Setter Property="Foreground" Value="Green" />
      </DataTrigger>
  </TextBlock.Triggers>
</TextBlock>

Вот XAML после исправления:

<TextBlock x:Name="Hello" Text="{Binding Hello, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <TextBlock.Style>
        <Style TargetType="TextBlock">
            <Setter Property="Foreground" Value="Red" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Hello}" Value="GoGreen">
                    <Setter Property="Foreground" Value="Green" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

Вот пример скриншота, показывающий, что если мы введем GoGreen, текст станет зеленым:

enter image description here

... и если мы введем что-то еще, текст по умолчанию будет красным:

enter image description here

В Интернете есть множество бесплатных материалов о триггерах WPF, и все они довольно неплохо объясняют концепцию, и эта страница заставила меня выбросить пенни .

4 голосов
/ 18 июля 2013

Это может быть безнадежно устаревшим, но следующее работает для меня. Это может помочь людям, сталкивающимся с проблемой: «Члены коллекции триггеров должны быть типа EventTrigger»

<Control>
  <Control.Template>
    <ControlTemplate >

      <!-- Design -->
      <StackPanel>
        <CheckBox Name="CollapseControl" Content="Show" IsChecked="False" />
        <Label Name="CollapseTarget" Content="MyContent" Visibility="Collapsed" />
      </StackPanel>

      <!-- Triggers -->
      <ControlTemplate.Triggers >
        <Trigger SourceName="CollapseControl" Property="IsChecked" Value="True" >
          <Setter TargetName="CollapseTarget" Property="Visibility" Value="Visible" />
        </Trigger>
      </ControlTemplate.Triggers>

    </ControlTemplate>
  </Control.Template>
</Control>

Инкапсуляция «того, что вы хотите контролировать» внутри объекта Control позволяет вам использовать Control.Template для использования любого триггера, который вы хотите. Таким образом, вы можете использовать триггеры (данные) непосредственно в своем XAML, где вы хотите, без определения статического стиля или совершенно нового UserControl.

4 голосов
/ 08 мая 2009

Вы также можете привязать видимость в своей стеке к свойству IsChecked в ToggleButton. Вам нужно будет использовать пользовательский ValueConverter. Вот один, который я нашел онлайн:

/// <summary>  
/// WPF/Silverlight ValueConverter : Convert boolean to XAML Visibility
/// </summary>  
[ValueConversion(typeof(bool), typeof(Visibility))]
public class VisibilityConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    return (value != null && (bool)value) ? Visibility.Visible : Visibility.Collapsed;
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    Visibility visibility = (Visibility)value;
    return (visibility == Visibility.Visible);
  }
}
...