c# - 如何在MVVM的上下文中处理DataGrid中的页眉单击事件?

标签 c# wpf events mvvm datagrid

我知道如何使用代码隐藏方法处理DataGrid WPF中的页眉单击事件:

<DataGrid>
    <DataGrid.Resources>
        <Style TargetType="DataGridColumnHeader">
            <EventSetter Event="Click" Handler="columnHeader_Click" />
        </Style>
    </DataGrid.Resources>
</DataGrid>

但是,我想在MVVM的上下文中处理此事件。我试图用System.Windows.Interactivity处理,但是我不知道应该在EventName里面写什么:
<DataGrid>
   <i:Interaction.Triggers>
      <i:EventTrigger EventName="What event can I use?"
   </i:Interaction.Triggers>
</DataGrid>

我已经看到诸如ColumnReorderedColumnReordering的事件,但是它不适用。

如何在MVVM的上下文中处理DataGrid WPF中的页眉单击事件?

最佳答案

您需要以标题样式设置触发器。交互触发器和行为通常不能以一种样式设置,因为TriggerCollection和BehaviorCollection类是密封的,因此您不能在XAML中声明它们。但是,用户vspivak发布了a workaround for this on the wordpress site,它基本上创建了自己的列表,并使它们与交互列表中的列表保持同步:

using System.Collections.Generic;
using System.Windows;
using System.Windows.Interactivity;

namespace YourApplication
{
    /// <summary>
    /// <see cref="FrameworkTemplate"/> for InteractivityElements instance
    /// <remarks>Subclassed for forward compatibility, perhaps one day <see cref="FrameworkTemplate"/> </remarks>
    /// <remarks>will not be partially internal</remarks>
    /// </summary>
    public class InteractivityTemplate : DataTemplate
    {

    }

    /// <summary>
    /// Holder for interactivity entries
    /// </summary>
    public class InteractivityItems : FrameworkElement
    {
        private List<Behavior> _behaviors;
        private List<System.Windows.Interactivity.TriggerBase> _triggers;

        /// <summary>
        /// Storage for triggers
        /// </summary>
        public List<System.Windows.Interactivity.TriggerBase> Triggers
        {
            get
            {
                if (_triggers == null)
                    _triggers = new List<System.Windows.Interactivity.TriggerBase>();
                return _triggers;
            }
        }

        /// <summary>
        /// Storage for Behaviors
        /// </summary>
        public List<Behavior> Behaviors
        {
            get
            {
                if (_behaviors == null)
                    _behaviors = new List<Behavior>();
                return _behaviors;
            }
        }

        #region Template attached property

        public static InteractivityTemplate GetTemplate(DependencyObject obj)
        {
            return (InteractivityTemplate)obj.GetValue(TemplateProperty);
        }

        public static void SetTemplate(DependencyObject obj, InteractivityTemplate value)
        {
            obj.SetValue(TemplateProperty, value);
        }

        public static readonly DependencyProperty TemplateProperty =
            DependencyProperty.RegisterAttached("Template",
            typeof(InteractivityTemplate),
            typeof(InteractivityItems),
            new PropertyMetadata(default(InteractivityTemplate), OnTemplateChanged));

        private static void OnTemplateChanged(
            DependencyObject d,
            DependencyPropertyChangedEventArgs e)
        {
            InteractivityTemplate dt = (InteractivityTemplate)e.NewValue;
#if(!SILVERLIGHT)
            dt.Seal();
#endif
            InteractivityItems ih = (InteractivityItems)dt.LoadContent();
            BehaviorCollection bc = Interaction.GetBehaviors(d);
            System.Windows.Interactivity.TriggerCollection tc = Interaction.GetTriggers(d);

            foreach (Behavior behavior in ih.Behaviors)
                bc.Add(behavior);

            foreach (System.Windows.Interactivity.TriggerBase trigger in ih.Triggers)
                tc.Add(trigger);
        }

        #endregion
    }
}

有了这个,将其简单地应用于ColumnHeaderStyle即可:
    <DataGrid.ColumnHeaderStyle>
        <Style TargetType="DataGridColumnHeader">
            <Setter Property="local:InteractivityItems.Template">
                <Setter.Value>
                    <local:InteractivityTemplate>
                        <local:InteractivityItems>
                            <local:InteractivityItems.Triggers>
                                <i:EventTrigger EventName="Click" >
                                    <i:InvokeCommandAction Command="{Binding DataContext.YourCommand,
                                        RelativeSource={RelativeSource AncestorType=DataGrid}}" />
                                </i:EventTrigger>
                            </local:InteractivityItems.Triggers>
                        </local:InteractivityItems>
                    </local:InteractivityTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.ColumnHeaderStyle>

有点笨拙,但可以。

关于c# - 如何在MVVM的上下文中处理DataGrid中的页眉单击事件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35705228/

相关文章:

c# - 上传后文件上传 Controller 不工作 - global.asax 上传后不触发

c# - Visual Studio 2010 Crystal 报告 wpf

javascript - 在通过导入/导出完成代码之前,我将如何防止事件发生?

c# - C# WPF MVVM 中的时间滴答

c# - 使用 lambda 语法覆盖

WPF 快速原型(prototype)设计。无需运行即可查看更改

javascript - 如果您选择相同的选项,则无法添加事件监听器来选择选项

.net - Winform - 这是用户控件最后触发的事件

c# - 使用 ASP .NET Core 2.0 从 Main 访问服务

wpf - 在wpf中设置按钮背景样式