Wpf:如何从嵌套的 DataGrid 中绑定 SelectedItem
Posted
技术标签:
【中文标题】Wpf:如何从嵌套的 DataGrid 中绑定 SelectedItem【英文标题】:Wpf: How to bind SelectedItem from nested DataGrid 【发布时间】:2021-12-08 15:11:27 【问题描述】:我不知道如何从嵌套的 DataGrid 中正确绑定 SelectedItem。在主 DataGrid 中,我有一个这样的绑定:
SelectedItem="Binding SelectedElement"
它工作正常 - 如果我在 MainVM 类的 DataGrid 属性 SelectedElement 中选择 element 设置为所选元素。 我在嵌套的 DataGrid 中有类似的绑定:
SelectedItem="Binding SelectedMyItem"
但它根本不起作用 - 当我在嵌套 DataGrid 中选择 item 时,属性 SelectedMyItem 仍然是 null。
我的问题: 如何绑定 SelectedMyItem 属性,以便在 DataGrid 中选择项目后对其进行设置?
我没有从 IDE 获得任何绑定错误信息。
这是一个显示我的问题的简单示例:
类:
using System.Collections.ObjectModel;
namespace NesteGridMVVM
public class MyItem
public string MyItemName get; set;
//======================================================================
public class Element
private MyItem _selectedItem;
public string ElementName get; set;
public ObservableCollection<MyItem> MyItemsList get; set; = new ObservableCollection<MyItem>();
//Binded to SelectedItem in nested DataGrid
public MyItem SelectedMyItem
get => _selectedItem;
set
_selectedItem = value;
//Show, if MyItem was selected - it not work.
System.Diagnostics.Debug.Print($"Selected MyItem: _selectedItem.MyItemName");
//======================================================================
public class MainVM
private Element _selectedElement;
public ObservableCollection<Element> ElementsList get; set; = new ObservableCollection<Element>();
//Binded to SelectedItem in main DataGrid
public Element SelectedElement
get => _selectedElement;
set
_selectedElement = value;
//Show, if Element was selected - it works OK
System.Diagnostics.Debug.Print($"_selectedElement.ElementName");
//ctor - populate view model
public MainVM()
Element elem1 = new Element() ElementName = "element-01" ;
Element elem2 = new Element() ElementName = "element-02" ;
elem1.MyItemsList.Add(new MyItem() MyItemName = "item-A" );
elem1.MyItemsList.Add(new MyItem() MyItemName = "item-B" );
elem2.MyItemsList.Add(new MyItem() MyItemName = "item-C" );
ElementsList.Add(elem1);
ElementsList.Add(elem2);
XAML:
<Window x:Class="NesteGridMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NesteGridMVVM"
mc:Ignorable="d"
Title="MainWindow" Height="550" Width="600">
<Window.DataContext>
<local:MainVM />
</Window.DataContext>
<DataGrid
x:Name="MainDG"
ItemsSource="Binding ElementsList"
AutoGenerateColumns="True"
SelectedItem="Binding SelectedElement"
RowDetailsVisibilityMode="Visible">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid
x:Name="NestedDG"
ItemsSource="Binding MyItemsList"
AutoGenerateColumns="True"
SelectedItem="Binding SelectedMyItem">
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Window>
【问题讨论】:
【参考方案1】:在我看来你可以将绑定触发器修改为PropertyChanged
:
SelectedItem="Binding SelectedMyItem, UpdateSourceTrigger=PropertyChanged"
不过,请注意:
当我在调试器中运行它时,嵌套的 DataGrid 选择在外部 DataGrid 之前触发。这意味着set
的SelectedMyItem
将在SelectedElement
之前触发。当然,这只是在您更改外部 DataGrid 中的行时。
完整的.xaml
:
<Window x:Class="NesteGridMVVM.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:NesteGridMVVM"
mc:Ignorable="d"
Title="MainWindow" Height="550" Width="600">
<Window.DataContext>
<local:MainVM />
</Window.DataContext>
<DataGrid
x:Name="MainDG"
ItemsSource="Binding ElementsList"
AutoGenerateColumns="True"
SelectedItem="Binding SelectedElement"
RowDetailsVisibilityMode="Visible">
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid
x:Name="NestedDG"
ItemsSource="Binding MyItemsList"
AutoGenerateColumns="True"
SelectedItem="Binding SelectedMyItem, UpdateSourceTrigger=PropertyChanged">
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
</Window>
【讨论】:
非常感谢。这正是我想要实现的,但我不明白为什么添加 UpdateSourceTrigger = PropertyChanged 可以解决问题? @AdamMroczek 通常只是 WPF 的一个怪癖,很多时候在WPF
中,绑定的默认触发器是当您离开字段或LostFocus
时。我猜测内部 DataGrid 的问题在于,它们每个都有自己独立的可聚焦对象,即使您单击另一个也可以保持“聚焦”。如果您想要一个示例,请使用带有默认文本绑定的TextBox
- 它不会触发,直到您点击/点击离开。将触发器更改为 PropertyChanged 会在您键入时触发。以上是关于Wpf:如何从嵌套的 DataGrid 中绑定 SelectedItem的主要内容,如果未能解决你的问题,请参考以下文章
WPF 使用 id 从数据库表中绑定 DataGrid 列 ComboBox
wpf中,当DataGrid.ItemsSource与ObservableCollection绑定后,值变化时,DataGrid如何刷新?
WPF DataGrid - 如何暂停数据绑定中的 UI 更新并稍后进行批量更新