2017-05-30 14 views
0

私は、支払いリストを表示するDataGridを持っています。バッキング変数/プロパティを更新せずにDataGridのSelectedItemにバインドできますか?

<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は、ObservableCollection of Paymentオブジェクトにバインドされています。

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... } 
    } 
} 

ご覧のとおり、各支払いには、各支払いの割り当て方法を示す予約オブジェクトのリストであるプロパティがあります。

予約オブジェクトはかなりシンプルです。

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; } 
} 

また、選択した支払いの予約オブジェクトの一覧を表示する2番目のDataGridがあります。私が期待したもの

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

は、私はDataGridの1で支払項目を選択したときに、データグリッド2は、その支払いが割り当てられたかの詳細が移入されるだろうということでした。私が得たものは、空の詳細DataGridでした。

私は、ViewModelのプロパティにSelectedItemプロパティを関連付け、そのプロパティが変更されるたびに通知することができますが、DataGrid 2はDataGrid 1のSelectedItemプロパティが自動的に変更されたことを知っている必要があります。あまりにも多くを求めているのですか、それとも間違っていますか?

+1

あなたが説明した内容はすばらしいはずですが、悪魔は詳細です。これを試して、実行時にVS出力ペインでマスターグリッドの選択を変更すると表示されているものを確認してください: 'ItemsSource =" {Binding SelectedItem.Bookings、ElementName = dataGrid、PresentationTraceSources.TraceLevel = High} "' –

+0

選択したアイテムの予約リストが空でないことを再度確認しますか?指定されたコードでエラーが表示されない –

+0

両方のDataGridが同じ名前付けスコープに存在する場合は、動作する必要があります。選択した支払いの予約コレクションに値が設定されていることを確認します。 – mm8

答えて

0

予約のプロパティが公開されていることを確認してください。

ます。また同様に、結合あなたのSelectedItemにUpdateSourceTrigger =にPropertyChangedを使用することがあります:これが解決しない場合はyesの場合、データはBookings-に実際にあることを確認するためにスヌープを使用してみてください、

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

、 VM内のプロパティを使用してデータクラスのINotifyPropetyChangedを実装するか、DataGrid1のSelectionChanged EventHandlerを使用してDataGrid2のプロパティを更新してください。

+0

これが問題でした。 My Bookingsプロパティがパブリックに設定されていませんでした。 –

+0

バインディングに 'UpdateSourceTrigger = PropertyChanged'を追加するという奇妙な提案のためにupvoteを取り消しました。あなたがそのことを示唆したら、それが何を意味するのかを知る必要はありませんそれは明らかにノーオペレーションです。そして、あなたが何をしているのか分からなければ、人々の拘束力に魔法の治癒効果があると自信を持って主張してはいけません。 –

0

設定

  1. は具体的のviewmodelにSelectedItemプロパティを追加し、子グリッドのは
  2. の結合において、「/」の構文を使用してWPFのリストから親子の選択を管理するための3つの一般的な方法は、あります。 親グリッドのそれと子のグリッド
  3. でそれを読んで宣言CollectionViewSourceに親グリッドをバインドしたときに のCurrentChangedイベントはCollectionViewSource火災 子グリッドのデータソースを設定します。

オプションが最も一般的です。個人的には、私はを使用する方が好きです。なぜなら、それは私のViewModelでMoveFirst/Last/Next/Previousの機能を提供するからです。

あなたはを探しているようですが、これは最も簡単な方法ですが、最も強力ではありません。子グリッドのバインドを

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

に変更するだけです。間違ったElementName参照を削除しました。親グリッドのプロパティではなく、DataContextにバインドしています。

+1

マスターDataGridのSelectedItemに直接バインドするのが間違っているのはなぜですか? –

+0

間違った単語を使用するのは間違っていました。それは "悪い習慣"だったでしょうフレーズするより良い方法。ソースコントロールの名前を変更するか、他のコンテキストで子コントロールを使用しようとすると、他のコントロールのプロパティにバインドされます。また、ソースコントロールの実装に依存するようになりました。これにより、SelectedItemプロパティが更新されるたびに何回も起動されることがあります。そして、最も重要なのは、プロパティ要素へのバインディングは単体テストにとってははるかに難しいことです。 –

関連する問題