触发器集合成员必须是EventTrigger类型

时间:2009-05-07 19:56:07

标签: .net wpf datatrigger

我创建了一个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在检查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 个答案:

答案 0 :(得分:36)

来自MSDN Docs,根据理查德·麦克奎尔的(略微转述)回答:

  

DataTriggers可用于XML标记样式 ControlTemplate DataTemplate

例如,如果您尝试向TextBlock添加触发器,则会生成此错误:

  

错误:触发器集合成员的类型必须为EventTrigger

为什么呢? Trigger只能放在StyleControlTemplateDataTemplate内,我们会尝试将其直接放在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触发器的免费资料,所有这些材料在解释这个概念方面做得相当不错,this page was the one that made the penny drop for me

答案 1 :(得分:14)

管理解决问题。忘记DataTriggers适用于MSDN Docs.

的Style,ControlTemplate和DataTemplate

解决方案是使用EventTrigger作为指示的错误消息。我的解决方案如下:

<EventTrigger RoutedEvent="ToggleButton.Checked">
    <BeginStoryboard>
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="LaunchButtons">
                <DiscreteObjectKeyFrame KeyTime="0:0:0"
                                        Value="{x:Static Visibility.Visible}" />
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="ToggleButton.Unchecked">
    <BeginStoryboard>
        <Storyboard>
            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility"
                                           Storyboard.TargetName="LaunchButtons">
                <DiscreteObjectKeyFrame KeyTime="0:0:0"
                                        Value="{x:Static Visibility.Collapsed}" />
            </ObjectAnimationUsingKeyFrames>
        </Storyboard>
    </BeginStoryboard>
 </EventTrigger>

如果其他人有另一种解决方案的话,请暂缓将此标记为答案。

答案 2 :(得分:4)

您还可以将stackpanel中的Visibility绑定到ToggleButton中的IsChecked属性。您需要使用自定义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);
  }
}

答案 3 :(得分:4)

这可能已经过时了,但以下情况对我有用。它可能会帮助人们遇到问题:“触发器集合成员必须是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。