使用DataTrigger动态设置事件处理程序

10

当特定条件满足时,我需要为多个ItemsControl 绑定 PreviewMouseLeftButtonDown 事件处理程序。

我已经设计了一种带有 DataTrigger 的样式,并检查了其绑定,并尝试使用<Setter>来设置 BorderThickness 属性以验证 DataTrigger 是否有效(它是有效的)。

如何通过事件 Setter 在符合 DataTrigger 条件时应用 DataTrigger 以绑定事件处理程序,就像使用常规属性 Setter 一样?

类似于以下内容:

     <Style TargetType="{x:Type ItemsControl}">                              
        <Style.Triggers>
            <DataTrigger Binding="{Binding Turn}" Value="True">
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="ItemsControl_MouseLeftButtonDown"></EventSetter>
            </DataTrigger>                            
        </Style.Triggers>
     </Style>

这个标记会在eventsetter行引发以下异常:

    'Set property 'System.Windows.EventSetter.Event' threw an exception.' 

内部异常:

       {"Value cannot be null.\r\nParameter name: value"}

哪一行代码抛出了异常?是 <DataTrigger Binding="{Binding Turn}" Value="True">' 吗? - XiaoChuan Yu
<EventSetter Event="PreviewMouseLeftButtonDown" Handler="ItemsControl_MouseLeftButtonDown"></EventSetter> - eran otzap
2个回答

18

根据MSDN文档中的备注,不幸的是:

请注意,仅有Style.Setters支持EventSetter对象。触发器(TriggerBase和派生类)不支持EventSetter。

在这种情况下,DataTrigger是从TriggerBase派生而来的,因此您不能使用它来动态设置事件处理程序。我现在能想到的一个解决方法可能是根据Turn的值动态切换样式。


我其实想注册一个依赖属性,类似于 my:mouseleftbuttondown="True",并在 setter 中使用它。我不知道是否可以在 setter 中使用自定义依赖属性。 - eran otzap
我有点怀疑它是否适合您的情况,但您可能想查看http://stackoverflow.com/questions/1138339/can-i-dynamically-switch-between-styles-in-wpf。 - XiaoChuan Yu
这是个好主意,我会基于我已有的样式设计一个新样式,并做出类似的东西。<ItemsControl Style="{Binding Turn,Converter={StaticResources MyTurnToStyleConverter}" /> - eran otzap
嗯,你打算如何获取样式的引用? - XiaoChuan Yu
我还不确定...现在没时间处理它,也许我可以给事件设置器的Handler值绑定一个值,然后将其设置为null或处理程序的引用,但我也不知道是否可能,当我弄清楚时,我会发布解决方案。 - eran otzap

0
您可以使用 StyleSelector
public sealed class NewItemPlaceholderStyleSelector : StyleSelector
{
    public Style? Style { get; set; }

    public override Style? SelectStyle(object? item, DependencyObject container)
    {
        if (NewItemPlaceholder.IsMatch(item))
        {
            return this.Style;
        }

        return base.SelectStyle(item, container);
    }
}

<DataGrid ...>
    <DataGrid.ItemContainerStyleSelector>
        <local:NewItemPlaceholderStyleSelector>
            <local:NewItemPlaceholderStyleSelector.Style>
                <Style TargetType="{x:Type DataGridRow}" BasedOn="{StaticResource {x:Type DataGridRow}}">
                    <EventSetter Event="MouseDoubleClick" Handler="OnMouseDoubleClick" />
                </Style>
            </local:NewItemPlaceholderStyleSelector.Style>
        </local:NewItemPlaceholderStyleSelector>
    </DataGrid.ItemContainerStyleSelector>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接