WPF 事件到父子 DataGrid 中的命令绑定无法绑定子 DataGrid 事件
WPF Event to Command Binding in Parent Child DataGrid failing to bind Child DataGrid Events
我想在 WPF 中对具有父子关系的 DataGrid 中的分层数据执行 CRUD 操作。为了显示子网格,我使用了一个 RowDetailsTemplate 设置为 StaticResource 的数据网格。作为上下文,我将 MVVM 模式与 Prism 框架和 Telerik 控件一起使用。
我已将两个子数据视图放在数据模板的选项卡控件中。该应用程序完美地显示数据。我的问题是子网格中的事件没有绑定到 ViewModel 中相应的委托命令。我尝试以不同的方式绑定子 DataGrids 中的事件但无济于事(在下面的代码中注释掉)。
我怀疑它与 Prism ViewModelLocator.AutoWireViewModel 有关,因为我在输出 Window 中遇到的绑定错误没有像我预期的那样引用我的 ViewModel。 (Location_14A...相对于 LocationViewModel)
System.Windows.Data 错误:40:BindingExpression 路径错误:'BeginEditCommand' 属性 未在 'object' ''Location_14A7828CEC09716B3DA7369A214EE4EE12A5B3DF727D10928AAFA56EF30AA046' (HashCode=59884855)' 上找到。 BindingExpression:Path=SubBeginEditCommand; DataItem='Location_14A7828CEC09716B3DA7369A214EE4EE12A5B3DF727D10928AAFA56EF30AA046' (哈希码=59884855);目标元素是 'EventBinding' (HashCode=66128121);目标 属性 是 'Command'(类型 'ICommand')
奇怪的是事件在父 DataGrid 中完美绑定,所以我确信我忽略了一些小东西。
我的DataTemplate如下:
<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>
我希望当我开始在子数据网格中编辑时调用委托命令,就像我在父数据网格中开始编辑时一样。
提前致谢
如果您有一个 BeginEditCommand
属性 定义在与 Bins
属性 相同的 class 中, RadGridView
绑定到,这个绑定应该在 RowDetailsTemplate
:
Command="{Binding DataContext.BeginEditCommand,
RelativeSource={RelativeSource AncestorLevel=2, AncestorType=telerik:RadGridView}}"
我的猜测是您在数据网格内的错误数据上下文中,至少我遇到了非常相似的问题(巧合的是 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/
我想在 WPF 中对具有父子关系的 DataGrid 中的分层数据执行 CRUD 操作。为了显示子网格,我使用了一个 RowDetailsTemplate 设置为 StaticResource 的数据网格。作为上下文,我将 MVVM 模式与 Prism 框架和 Telerik 控件一起使用。
我已将两个子数据视图放在数据模板的选项卡控件中。该应用程序完美地显示数据。我的问题是子网格中的事件没有绑定到 ViewModel 中相应的委托命令。我尝试以不同的方式绑定子 DataGrids 中的事件但无济于事(在下面的代码中注释掉)。
我怀疑它与 Prism ViewModelLocator.AutoWireViewModel 有关,因为我在输出 Window 中遇到的绑定错误没有像我预期的那样引用我的 ViewModel。 (Location_14A...相对于 LocationViewModel)
System.Windows.Data 错误:40:BindingExpression 路径错误:'BeginEditCommand' 属性 未在 'object' ''Location_14A7828CEC09716B3DA7369A214EE4EE12A5B3DF727D10928AAFA56EF30AA046' (HashCode=59884855)' 上找到。 BindingExpression:Path=SubBeginEditCommand; DataItem='Location_14A7828CEC09716B3DA7369A214EE4EE12A5B3DF727D10928AAFA56EF30AA046' (哈希码=59884855);目标元素是 'EventBinding' (HashCode=66128121);目标 属性 是 'Command'(类型 'ICommand')
奇怪的是事件在父 DataGrid 中完美绑定,所以我确信我忽略了一些小东西。
我的DataTemplate如下:
<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>
我希望当我开始在子数据网格中编辑时调用委托命令,就像我在父数据网格中开始编辑时一样。
提前致谢
如果您有一个 BeginEditCommand
属性 定义在与 Bins
属性 相同的 class 中, RadGridView
绑定到,这个绑定应该在 RowDetailsTemplate
:
Command="{Binding DataContext.BeginEditCommand,
RelativeSource={RelativeSource AncestorLevel=2, AncestorType=telerik:RadGridView}}"
我的猜测是您在数据网格内的错误数据上下文中,至少我遇到了非常相似的问题(巧合的是 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/