如何在MVVM的上下文中处理DataGrid中的Header点击事件?
问题描述:
我知道如何使用代码隐藏的方式在DataGrid的WPF处理标题单击事件:如何在MVVM的上下文中处理DataGrid中的Header点击事件?
<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>
我见过的事件,如ColumnReordered
,ColumnReordering
,但它是不适用的。
如何在MVVM的上下文中处理DataGrid WPF中的Header单击事件?
答
您需要在标题样式中设置触发器。因为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>
位kludgy,但它的作品。
@downvoter反对的原因是什么? – StepUp
当然是事件的名称。所以“点击” – CathalMF
@CathalMF没有这样的事件! – StepUp