首页 > 解决方案 > 从样式中将项目添加到集合

问题描述

我有一种以网格内的 DataGrids 为目标的样式。

<Grid.Resources>
    <Style TargetType="DataGrid">
        <Setter Property="IsReadOnly" Value="True" />
        <Setter Property="AutoGenerateColumns" Value="False" />
    </Style>
</Grid.Resources>

我想在样式中添加一个 EventTrigger(使用WPF 的 Microsoft XAML 行为库)。

<b:EventTrigger EventName="SelectionChanged">
    <b:InvokeCommandAction Command="{Binding UpdateSelection}" CommandParameter="{Binding SelectedItem}" />
</b:EventTrigger>

然而,这:

<Grid.Resources>
    <Style TargetType="DataGrid">
        <Setter Property="IsReadOnly" Value="True" />
        <Setter Property="AutoGenerateColumns" Value="False" />
        <Setter Property="b:Interaction.Triggers">
            <Setter.Value>
                <b:EventTrigger EventName="SelectionChanged">
                    <b:InvokeCommandAction Command="{Binding UpdateSelection}" CommandParameter="{Binding SelectedItem}" />
                </b:EventTrigger>
            </Setter.Value>
        </Setter>
    </Style>
</Grid.Resources>

失败,出现XamlParseException

'设置属性'System.Windows.Setter.Property' 引发异常。行号“28”和行位置“22”。

内部异常 1:
ArgumentNullException:值不能为空。
参数名称:属性

尽管报告的异常似乎无关紧要,但我认为这是因为我试图Interaction.Triggers使用单个 设置附加的集合属性EventTrigger,而不是添加EventTrigger到集合中。

如何在 XAML 中的样式中将项目添加到集合中?

标签: wpfxaml

解决方案


您不能在Style. 不支持。

您可以做的是定义一个连接事件处理程序的附加行为:

public class SelectionChangedBehavior
{
    public static ICommand GetCommand(DataGrid dataGrid)
    {
        return (ICommand)dataGrid.GetValue(CommandProperty);
    }

    public static void SetCommand(DataGrid dataGrid, ICommand value)
    {
        dataGrid.SetValue(CommandProperty, value);
    }

    public static object GetCommandParameter(DataGrid dataGrid)
    {
        return dataGrid.GetValue(CommandParameterProperty);
    }

    public static void SetCommandParameter(DataGrid dataGrid, object value)
    {
        dataGrid.SetValue(CommandParameterProperty, value);
    }

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached(
        "Command",
        typeof(ICommand),
        typeof(SelectionChangedBehavior),
        new UIPropertyMetadata(null, OnCommandChanged));

    public static readonly DependencyProperty CommandParameterProperty =
        DependencyProperty.RegisterAttached(
        "CommandParameter",
        typeof(object),
        typeof(SelectionChangedBehavior),
        new UIPropertyMetadata(null));


    private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        DataGrid dataGrid = d as DataGrid;
        if (dataGrid != null)
            dataGrid.SelectionChanged += OnSelectionChanged;
    }

    private static void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        DataGrid dataGrid = (DataGrid)sender;
        ICommand command = GetCommand(dataGrid);
        if (command != null)
            command.Execute(GetCommandParameter(dataGrid));
    }
}

XAML:

<Style TargetType="DataGrid" xmlns:local="clr-namespace:WpfApp1">
    <Setter Property="IsReadOnly" Value="True" />
    <Setter Property="AutoGenerateColumns" Value="False" />
    <Setter Property="local:SelectionChangedBehavior.Command" Value="{Binding UpdateSelection}" />
    <Setter Property="local:SelectionChangedBehavior.CommandParameter" Value="{Binding SelectedItem}" />
</Style>

WpfApp1指上SelectionChangedBehavior例中类的命名空间。


推荐阅读