我创建了一个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>
答案 0 :(得分:36)
来自MSDN Docs,根据理查德·麦克奎尔的(略微转述)回答:
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
,则文字变为绿色:
...如果我们输入其他内容,则文本默认为红色:
网上有很多关于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。