首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >i:Interaction.Triggers在DataTemplate里面?

i:Interaction.Triggers在DataTemplate里面?
EN

Stack Overflow用户
提问于 2017-11-10 19:48:30
回答 1查看 1.6K关注 0票数 0

我一直在使用i:Interaction.Triggers和EventToCommand实现来处理VM中的某些控制事件。

代码语言:javascript
复制
<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,所以我创建了一个具有交互触发器的DataGrid的ItemsControl模板。我注意到在这种情况下,触发器不起作用。

这是众所周知的问题吗?我调试了EventToCommand类,它正在调用附加成员,但它从不调用调用。

ItemsControl看起来像:

代码语言:javascript
复制
<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" />

有什么想法吗?我做错了什么吗?

编辑:

代码语言:javascript
复制
<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>
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-11-12 18:40:02

这是System.Windows.Interactivity EventTrigger的问题和某些情况的结合。

Interactivity.EventTrigger无法处理在FrameworkElement.Loaded事件之前触发的事件

它在内部使用关联对象的加载事件来为除加载事件本身以外的所有事件附加事件处理程序。您的EventToCommand中的EventToCommand方法是从TriggerAction.Attach调用的,它实际上将TriggerAction附加到关联的对象(这里是DataGrid)。AssociatedObject属性在TriggerAction上不是一个DependencyProperty,而且由于TriggerAction继承了Freezable,所以这个方法可以执行可冻结的相关内容(调用WritePreambleWritePostscript)。实际事件处理程序尚未附加。

DataGrid AutoGeneratingColumn和LoadingRow

如果ItemsSource可以在初始化DataGrid时确定(DataGrid可以确定需要生成哪些列和行),则这些事件会在加载事件之前触发。我假设当您的DataGrid不是DataTemplate的一部分时,它的ItemsSource绑定到VM上的一个属性,在初始化DataGrid时,该属性的值为null。一旦您将DataGrid移动到DataTemplate,当您为每个ItemControl的项设置了ItemsControl和DataGrids的ItemsSource属性时,就可以在初始化期间确定DataGrid的ItemsSource,并在加载事件之前触发这些事件。如果允许用户向DataGrid添加行(IsReadOnly为false,CanUserAddRows为true),则在DataGrid.IsLoaded变为true和用户添加一行之后将执行LoadingRowCommand

要使此操作正常,您必须在ItemsSource中不设置DataGrid的DataTemplate (基本上删除ItemsSource={Binding}),等待加载的事件,然后设置它。我会说,这违背了项目模板的概念(并且有一个很好的方法来做到这一点吗?),所以我会支持这两个事件的附加行为,就像您在评论中建议的那样。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47230118

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档