2013-02-06 74 views
0

我有一個綁定到Dictionary<string, DataTable>的選項卡式小部件。選項卡名稱綁定到詞典Keys,並且選項卡內容綁定到DataTables。這一切都加載正常,但在施工後的某個未指定的位置,所有表格都被重建爲更大更復雜的表格。我的問題是如何提供更改通知,以便WPF正確更新表格?獲取WPF更新DataTable的綁定列表

這似乎是一個非常明顯的事情要做,我想知道如果我錯過了什麼,或者我真的需要使用可觀察字典構造或自定義DataTable包裝與更改通知?

解決方案到目前爲止,我曾嘗試:

  • 使用一個ObservableCollection< KeyValuePair<string, DataTable>和添加或刪除條目。這實際上工作正常,但最終與視覺效果不吸引人的標籤消失和重新出現時,表需要得到更新

  • 我可以使用代碼隱藏黑客,但想避免這種情況如果可能的話。

這裏是XAML

<TabControl ItemsSource="{Binding StringToDataTableDictionary}" > 
    <TabControl.ItemTemplate> 
    <DataTemplate> 
     <Label Content="{Binding Key}" /> 
    </DataTemplate> 
    </TabControl.ItemTemplate> 
    <TabControl.ContentTemplate> 
    <DataTemplate> 
     <igDP:XamDataGrid DataSource="{Binding Path=Value}" 
    </DataTemplate> 
    </TabControl.ContentTemplate> 
</TabControl> 

回答

0

最後,沒有收藏通知機制解決我的問題。我想這是因爲在幕後,WPF持有對DataTable的引用,並且這是需要提供更改通知的引用。我意識到我可以刪除並重新添加表到集合中,但這導致GUI過慢。所以,我建立了提供變更通知的DataTable包裝,在這裏看到:

public class DataTableWithNotification : INotifyPropertyChanged 
{ 
    private DataTable _theTable = new DataTable(); 

    public DataTableWithNotification() 
    { 
    } 

    public DataTableWithNotification(DataTable dt) 
    { 
     _theTable = dt; 
    } 

    public DataTable Table 
    { 
     get { return _theTable; } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    public void ChangeTableAndNotify(DataTable newTable) 
    { 
     _theTable = newTable; 

     OnPropertyChanged("Table"); 
    } 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) 
     { 
      handler(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 
0

因此,在這一天結束時,你需要實現INotifyCollectionChangedIEnumerable(如ObservableCollection,或ICollectionView)一類。但是,當然,你可以自己創造一個。主要的是你在你的類中實現了兩個接口,然後在集合改變時調用CollectionChanged

一個簡單的例子:

class MyObservableDictionary<T, U> : INotifyCollectionChanged, IEnumerable 
{ 
    Dictionary<T, U> items = new Dictionary<T,U>(); 

    public void Add(T key, U value) 
    { 
     this.items.Add(key, value); 

     // Update any listeners 
     if (CollectionChanged != null) 
      CollectionChanged(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); 
    } 

    // This is from implementing INotifyCollectionChanged 
    public event NotifyCollectionChangedEventHandler CollectionChanged; 

    // This is from implementing IEnumerable 
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() 
    { 
     // Dump the entire collection into a 'yield return'. C# will automatically 
     // build an enumerator class from it. 
     foreach (KeyValuePair<T, U> item in items) 
      yield return item; 
    } 
} 

正如你可以看到,當我添加一個項目我要確保CollectionChanged不爲空(即,有人在監視這個類集合的變化),然後我調用它。這會提示監視對象呼叫GetEnumerator。在GetEnumerator函數中,我只是爲每個項目和'yield return'做一個每個項目(它告訴c#自動建立一個枚舉器,所以我不必自己做)。

的XAML:

<ListBox ItemsSource="{Binding Items}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <StackPanel Orientation="Horizontal"> 
       <Label Content="{Binding Key}" FontWeight="Bold"/> 
       <Label Content="{Binding Value}"/> 
      </StackPanel> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 
+0

是啊,我看你在說什麼,但是這並沒有解決我的問題,因爲我的收藏實際上並沒有改變,只是數據表內集合。 – saltyseadog