我一直在使用i:Interaction.Triggers和EventToCommand实现来处理我的VM中的某些控制事件。
<DataGrid ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="AutoGeneratingColumn">
<ui:EventToCommand Command="{Binding Path=DataContext.AutoGeneratingColumnCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
PassEventArgsToCommand="True" />
一切正常。然后我需要有多个DataGrids,所以我创建了一个ItemsControl模板,其中包含带有交互触发器的DataGrid。我注意到在这种情况下,触发器无效。
这是一个已知问题吗?我调试了EventToCommand类,它正在调用Attach成员,但它从不调用Invoke。
ItemsControl看起来像:
<ItemsControl>
<ItemsControl.ItemsTemplate>
<DataGrid ...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="AutoGeneratingColumn">
<ui:EventToCommand Command="{Binding Path=DataContext.AutoGeneratingColumnCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
PassEventArgsToCommand="True" />
有什么想法吗?我做错了吗?
编辑:
<ItemsControl Grid.Row="2" ItemsSource="{Binding StoredProcedureResults}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<DataGrid EnableColumnVirtualization="True" EnableRowVirtualization="True" SelectionMode="Extended" SelectionUnit="CellOrRowHeader"
CanUserAddRows="False" CanUserDeleteRows="False" IsReadOnly="True" BorderThickness="0,0,0,0" ItemsSource="{Binding}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="AutoGeneratingColumn">
<UI:EventToCommand Command="{Binding Path=DataContext.AutoGeneratingColumnCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
<i:EventTrigger EventName="LoadingRow">
<UI:EventToCommand Command="{Binding Path=DataContext.LoadingRowCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"
PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
答案 0 :(得分:1)
这是System.Windows.Interactivity
EventTrigger问题和某些情况的组合。
它在内部使用关联对象的Loaded事件来为除Loaded事件本身之外的所有事件附加事件处理程序。来自OnAttached
的{{1}}方法是从EventToCommand
调用的,它实际上将TriggerAction.Attach
附加到关联对象(此处为DataGrid)。 TriggerAction
上的AssociatedObject
属性不是DependencyProperty,而TriggerAction
继承自TriggerAction
,此方法会执行freezable相关内容(调用Freezable
和{{1} })。实际的事件处理程序尚未附加。
如果在初始化DataGrid时可以确定ItemsSource(DataGrid可以确定需要生成哪些列和行),则这些事件在Loaded事件之前触发。我假设当你的DataGrid不是DataTemplate的一部分时,它的ItemsSource被绑定到VM上的一个属性,在初始化DataGrid时它的值为null。将DataGrid移动到DataTemplate后,当您为ItemsControl设置WritePreamble
属性并为每个ItemControl的Item初始化DataGrids时,可以在初始化期间确定DataGrid的WritePostscript
这些事件在Loaded事件之前触发。如果您允许用户向DataGrid添加行(ItemsSource
为false,ItemsSource
为true),则IsReadOnly
将在CanUserAddRows
变为true后执行,并且用户添加了行。
要使其工作,您必须不要在DataTemplate中设置DataGrid的LoadingRowCommand
(基本上删除DataGrid.IsLoaded
),等待Loaded事件然后设置它。我说这违背了项目模板的想法(并且有一种很好的方法可以做到这一点吗?),所以我会按照你在评论中的建议去寻找这两个事件的附加行为。