2017-05-30 85 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綁定到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... } 
    } 
} 

正如您所看到的,每筆付款都有一個屬性,它是一個預訂對象列表,顯示每個付款的分配方式。

預訂對象非常簡單。

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屬性已自動更改。我問的太多了,還是我做錯了?

+1

你所描述的應該沒問題,但是惡魔在細節中。試試這個,看看你在VS輸出窗格中運行時看到了什麼,當你改變主網格中的選擇時:'ItemsSource =「{Binding SelectedItem.Bookings,ElementName = dataGrid,PresentationTraceSources.TraceLevel = High}」' –

+0

Did you仔細檢查selectedItem的預訂列表是否不爲空?不能看到與給定的代碼的錯誤 –

+0

應該工作,如果兩個DataGrids駐留在相同的命名範圍。確保所選付款的預訂集合已填充。 – mm8

回答

0

確保預訂的屬性是公共的。

你也可能需要使用UpdateSourceTrigger =的PropertyChanged在你的SelectedItem結合,如:

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

如果這沒有幫助,請嘗試使用史努比,以確保數據實際上是在Bookings-如果是,它不會顯示,或者與虛擬機中的屬性一起使用,並在您的數據類中實現INotifyPropetyChanged,或者通過datagrid1的SelectionChanged更新DataGrid2的屬性EventHandler

+0

這是問題所在。我的預訂屬性未設置爲公開。 –

+0

由於向綁定中添加'UpdateSourceTrigger = PropertyChanged'的荒謬建議而被撤銷upvote。如果你提出這個建議,你一定不知道這意味着什麼;這顯然是無用的。如果你不知道它的作用,不要對它有任何自信的聲明,說它對人的綁定有任何神奇的療效。 –

0

有三種常見的方式從列表管理父子選擇在WPF

  1. 用在孩子電網的結合
  2. 了「/」的語法具體的視圖模型添加SelectedItem屬性,設置它在 父柵格和在子網格
  3. 讀取它的父網格以聲明綁定到CollectionViewSource並設置 子網格的數據源時的 的CurrentChanged事件CollectionViewSource火災。

選項是最常見的。就個人而言,我更喜歡使用,因爲它使我能夠在我的視圖模型中移動第一個/最後/下一個/上一個。

你似乎在尋找,這是最簡單的方法,但也是最不強大的。您只需將您的子網格中的綁定更改爲

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

注意我已經刪除了ElementName引用,這是錯誤的;你綁定到你的DataContext,而不是父網格上的屬性。

+1

爲什麼直接綁定到主DataGrid的SelectedItem是錯誤的? –

+0

錯誤是不正確的詞使用。一個更好的方式來說這將是「不好的做法」。如果您重命名源代碼管理或嘗試在任何其他上下文中使用您的子控件,則綁定到其他控件上的屬性會中斷。另外,您現在依賴於源代碼管理的實現,它可能在刷新時觸發SelectedItem屬性任意次數。而最重要的是,綁定到一個屬性元素更難以進行單元測試。 –

相關問題