我可以绑定到DataGrid的SelectedItem而无需更新支持变量/属性吗?

时间:2017-05-30 14:54:18

标签: c# wpf binding datagrid

所以,我有一个显示付款清单的DataGrid。

<DataGrid x:Name="dataGrid" ItemsSource="{Binding Payments}" AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Header="PaymentDate" Binding="{Binding PaymentDate, StringFormat=\{0:d\}}" />
        <DataGridTextColumn Header="Amount" Binding="{Binding Amount, StringFormat=\{0:N\}}" />
        <DataGridTextColumn Header="Comment" Binding="{Binding Comment}" />
        <DataGridTextColumn Binding="{Binding EventCode}" Header="Event Code"/>
        <DataGridTextColumn Binding="{Binding DueDate, StringFormat=\{0:d\}}" Header="DueDate"/>
    </DataGrid.Columns>
</DataGrid>

此DataGrid绑定到Payment对象的ObservableCollection。

public class Payment
{
    public Guid ID { get; set; }

    public DateTime PaymentDate { get; set; }

    public decimal Amount { get; set; }

    public string Comment { get; set; }

    public string EventCode { get; set; }

    public DateTime? DueDate { get; set; }

    List<Booking> Bookings
    {
        get { ...magic that retrieves booking info... }
    }
}

如您所见,每笔付款都有一个属性,即预订对象列表,显示每笔付款的分配方式。

Booking对象非常简单。

public class Booking
{
    public string EventCode { get; set; }

    public decimal Amount { get; set; }

    public DateTime? BookingDate { get; set; }

    public string Designation { get; set; }

    public string Comment { get; set; }
}

我还有第二个DataGrid,它应显示所选付款的预订对象列表。

<DataGrid ItemsSource="{Binding SelectedItem.Bookings, ElementName=dataGrid}" AutoGenerateColumns="True" />

我的预期是,每当我在DataGrid 1中选择一个付款项目时,DataGrid 2都会填充有关该付款分配方式的详细信息。然而,我得到的是一个空的细节DataGrid。

我知道我可以将SelectedItem属性绑定到我的ViewModel中的属性,并在每次更改属性时通知我的View,但似乎DataGrid 2应该知道DataGrid 1的SelectedItem属性已自动更改。我问得太多了,还是我做错了?

2 个答案:

答案 0 :(得分:0)

从WPF列表中管理父子选择有三种常用方法

  1. 在子网格的绑定中使用“/”语法
  2. 在viewmodel中添加SelectedItem属性,将其设置为 父网格并在子网格中读取它
  3. 声明性地将父网格绑定到CollectionViewSource并进行设置 CurrentChanged事件时子网格的数据源 将触发CollectionViewSource。
  4. 选项 2 是最常见的。就个人而言,我更喜欢使用 3 ,因为它让我能够在我的视图模型中使用MoveFirst / Last / Next / Previous。

    您似乎在寻找 1 ,这是最简单的方式,也是最不强大的方式。您需要做的就是将子网格中的绑定更改为

    <DataGrid ItemsSource="{Binding Payments/Bookings}" AutoGenerateColumns="True" />
    

    注意我已经删除了ElementName引用,这是错误的;你绑定到你的DataContext,而不是父网格上的属性。

答案 1 :(得分:0)

确保预订的属性是公共属性。

您可能还想在SelectedItem绑定中使用UpdateSourceTrigger = PropertyChanged,如:

ItemsSource="{Binding SelectedItem.Bookings, ElementName=dataGrid, UpdateSourceTrigger=PropertyChanged}"

如果这没有帮助,请尝试使用Snoop确保数据实际位于预订中 - 如果是,并且未显示,请使用VM中的属性并在数据类中实现INotifyPropetyChanged,或者更新属性datagrid2通过datagrid1的SelectionChanged EventHandler