【问题标题】:WPF Event to Command Binding in Parent Child DataGrid failing to bind Child DataGrid EventsWPF 事件到父子 DataGrid 中的命令绑定无法绑定子 DataGrid 事件
【发布时间】:2019-08-21 14:39:18
【问题描述】:

我想对 WPF 中具有父子关系的 DataGrid 中的分层数据执行 CRUD 操作。为了显示子网格,我使用了一个 RowDetailsTemplate 设置为 StaticResource 的数据网格。作为上下文,我将 MVVM 模式与 Prism 框架和 Telerik 控件一起使用。

我已将两个子数据视图放在数据模板中的选项卡控件中。该应用程序完美地显示数据。我的问题是子网格中的事件没有绑定到 ViewModel 中的相应委托命令。我试图以不同的方式绑定子数据网格中的事件无济于事(在下面的代码中注释掉)。

我怀疑它与 Prism ViewModelLocator.AutoWireViewModel 有关,因为我在输出窗口中遇到的绑定错误没有像我预期的那样引用我的 ViewModel。 (Location_14A...而不是LocationViewModel)

System.Windows.Data 错误:40:BindingExpression 路径错误:在“对象”“Location_14A7828CEC09716B3DA7369A214EE4EE12A5B3DF727D10928AAFA56EF30AA046”(HashCode=59884855)上找不到“BeginEditCommand”属性。 BindingExpression:Path=SubBeginEditCommand; DataItem='Location_14A7828CEC09716B3DA7369A214EE4EE12A5B3DF727D10928AAFA56EF30AA046' (HashCode=59884855);目标元素是“EventBinding”(HashCode=66128121);目标属性是“Command”(输入“ICommand”)

奇怪的是事件在父数据网格中完美绑定,所以我确信我忽略了一些小东西。

我的数据模板如下:

<DataTemplate x:Key="RowDetailsTemplate">
                <telerik:RadTabControl>
                    <telerik:RadTabItem Header="Bins">
                        <telerik:RadGridView Name ="bins"
                                     ItemsSource="{Binding Bins, Mode=TwoWay}">

                            <i:Interaction.Triggers>
                                <i:EventTrigger EventName="BeginningEdit">
                                    <i:InvokeCommandAction Command="{Binding BeginEditCommand}"/>
                                </i:EventTrigger>
                            </i:Interaction.Triggers>

                            <!--<telerik:EventToCommandBehavior.EventBindings>
                                <telerik:EventBinding Command="{Binding BeginEditCommand}" EventName="BeginningEdit"  PassEventArgsToCommand="True"/>
                            </telerik:EventToCommandBehavior.EventBindings>-->

                            <telerik:RadGridView.Columns>
                                <telerik:GridViewDataColumn Header="Description" DataMemberBinding="{Binding Description, Mode=TwoWay}"/>
                            </telerik:RadGridView.Columns>
                        </telerik:RadGridView>
                    </telerik:RadTabItem>
                </telerik:RadTabControl>
            </DataTemplate>

我的父网格视图很简单:

        <telerik:RadGridView Grid.Row ="0"
                             Name ="MainGridView"
                             ItemsSource="{Binding MainCollection, Mode=TwoWay}"
                             AutoGenerateColumns="False"
                             SelectedItem="{Binding SelectedRecord, Mode=TwoWay}"
                             SelectionMode="Extended"
                             RowDetailsTemplate="{StaticResource RowDetailsTemplate}">

            <telerik:EventToCommandBehavior.EventBindings>
                <telerik:EventBinding Command="{Binding BeginEditCommand}" EventName="BeginningEdit"  PassEventArgsToCommand="True"/>
            </telerik:EventToCommandBehavior.EventBindings>

            <telerik:RadGridView.Columns>
                <telerik:GridViewToggleRowDetailsColumn/>
                <telerik:GridViewDataColumn Header="Location Id" 
                                            DataMemberBinding="{Binding Id, Mode=OneWay}" 
                                            IsReadOnly="True"/>
              <!--Removed for Bevity-->
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>

我希望在子数据网格中开始编辑时调用委托命令,就像在父数据网格中开始编辑时一样。

提前致谢

【问题讨论】:

  • 您能否实际显示使用ViewModelLocator 的代码,因为您怀疑它会导致问题?

标签: c# wpf mvvm prism


【解决方案1】:

如果您有一个BeginEditCommand 属性定义在与RadGridView 绑定到的Bins 属性相同的类中,则此绑定应该在RowDetailsTemplate 中起作用:

Command="{Binding DataContext.BeginEditCommand, 
    RelativeSource={RelativeSource AncestorLevel=2, AncestorType=telerik:RadGridView}}"

【讨论】:

  • 谢谢,当我最初尝试这个选项时,我犯的错误是没有用 Telerik 正确地为 AncestorType 添加前缀:所以我想如果在可视化树中找不到它是完全合乎逻辑的。愚蠢的错误..
【解决方案2】:

我的猜测是您在数据网格内的数据上下文中存在错误,至少我遇到了非常相似的问题(巧合的是 Telerik 和 Prism)。 MM8 有一个可能有效的解决方案,但如果 relativesource 不起作用,另一种对我有用的方法是引入 BindingProxy。 这个想法是您创建一个只包含数据上下文的资源,然后您可以将此资源作为数据网格中的静态资源引用。

在我的代码中是这样的:

<UserControl.Resources>
    <ResourceDictionary>
        <helpers:BindingProxy x:Key="DataContextProxy" Data="{Binding}" />
    </ResourceDictionary>
</UserControl.Resources>

绑定将是:

{Binding Path=Data.BeginEditCommand, Source={StaticResource DataContextProxy}

绑定代理的代码及原意来自本站: https://thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

【讨论】:

  • 这是个好主意,我一定会派上用场的。 MM8 的解决方案在这种情况下是一个简单的修复,因为我在正确的数据上下文中。
猜你喜欢
  • 2010-12-21
  • 2012-02-23
  • 1970-01-01
  • 1970-01-01
  • 2021-08-29
  • 1970-01-01
  • 1970-01-01
  • 2012-06-11
  • 2014-11-06
相关资源
最近更新 更多