【问题标题】:Triggers collection members must be of type EventTrigger触发器集合成员必须是 EventTrigger 类型
【发布时间】:2021-10-28 23:48:42
【问题描述】:

我创建了一个 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>

【问题讨论】:

    标签: .net wpf datatrigger


    【解决方案1】:

    设法弄明白了。根据MSDN Docs. 忘记了 DataTriggers 是为 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】:

      您还可以将堆栈面板中的 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】:

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

          来自MSDN Docs,根据 Richard C. McGuire 的(略微转述的)回答:

          DataTriggers 可以与 XML 标签 StyleControlTemplateDataTemplate

          一起使用

          例如,如果您尝试将触发器添加到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,文本变为绿色:

          ...如果我们输入其他内容,则文本默认为红色:

          网络上有大量关于 WPF 触发器的免费材料,所有这些材料都很好地解释了这个概念,this page was the one that made the penny drop for me

          【讨论】:

          • 如果你已经在你的 UI 控件上设置了一个 Style 资源(就像我遇到的那样),为了避免进一步的错误,只需将它变成具有 DataTrigger 的本地样式。如:&lt;TextBlock.Style&gt; &lt;Style TargetType="TextBlock" BasedOn="{StaticResource YourPreviousStyleResource}"&gt; &lt;Style.Triggers&gt; &lt;DataTrigger ...HTH
          猜你喜欢
          • 2018-10-26
          • 1970-01-01
          • 2015-03-16
          • 2013-01-23
          • 2023-01-23
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多