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

发布于 2024-07-19 02:33:25 字数 882 浏览 5 评论 0原文

我创建了一个 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 使“Launch”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>

I've created a UserControl, similar to the following:

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

I've been trying to use a DataTrigger to make the 'Launch' StackPanel become visible when the ToggleButton is checked, and remain collapsed otherwise. However, at runtime I get an error stating "Failed object initialization (ISupportInitialize.EndInit). Triggers collection members must be of type EventTrigger". I've tried adding it to the trigger collection of the UserControl and StackPanel with no success. My trigger XAML looks like the following:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

才能让你更想念 2024-07-26 02:33:25

来自 MSDN 文档,按照(稍微转述)理查德·麦奎尔的回答:

DataTriggers 可与 XML 标记 StyleControlTemplateDataTemplate

一起使用

例如,如果您尝试将触发器添加到 TextBlock< /code>,它将生成此错误:

错误:触发器集合成员必须为 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 触发器的免费材料,而且它们都做得相当不错解释这一概念的工作,此页面是赚一分钱的页面为我下降

From MSDN Docs, as per the (slightly paraphrased) answer from Richard C. McGuire:

DataTriggers can be used with XML tags Style, ControlTemplate and DataTemplate

For example, if you attempt to add a trigger to a TextBlock, it will generate this error:

Error: Triggers collection members must be of type EventTrigger

Why? A Trigger can only be placed inside a Style, ControlTemplate or DataTemplate, and we are trying to place it directly inside a TextBlock.

In this case, the fix is easy: just wrap the trigger in a style, then place this style inside the TextBlock, and the error will disappear.

Here is the error-generating XAML before the fix:

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

Here is the XAML after the fix:

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

Here is a sample screenshot showing that if we enter GoGreen, the text goes green:

enter image description here

... and if we enter something else, the text defaults to red:

enter image description here

There is loads of free material on the web about WPF triggers, and all of them do a reasonably good job of explaining the concept, and this page was the one that made the penny drop for me.

年少掌心 2024-07-26 02:33:25

根据 MSDN 文档,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>

DataTriggers are meant for Style, ControlTemplate and DataTemplate per the MSDN Docs.

Solution was to use an EventTrigger as the error message indicated. My solution was the following:

<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>
风和你 2024-07-26 02:33:25

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

This may be hopelessly outdated, but the following works for me. It might help people running into the problem with: "Triggers collection members must be of type 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>

Encapsulating "what you want to control" inside a Control object allows you to use the Control.Template to use any trigger you want. This way you can use (data)triggers directly in your XAML where you want to without defining a static style or a completely new UserControl.

吹梦到西洲 2024-07-26 02:33:25

您还可以将 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) =>
        value != null && (bool)value ? Visibility.Visible : Visibility.Collapsed;
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
        (Visibility)value == Visibility.Visible;
}

You could also bind the Visibility in your stackpanel to the IsChecked property in the ToggleButton. You would need to use a custom ValueConverter. Here is one I found online:

/// <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) =>
        value != null && (bool)value ? Visibility.Visible : Visibility.Collapsed;
 
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
        (Visibility)value == Visibility.Visible;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文