2017-02-09 84 views
0

這不是一個我堅持的問題,而是一個問題,以確定是否有更好的方法。它的工作原理如下,但我希望能夠更好地理解。組合框更改後更改ObservableCollection

爲什麼我總是必須更新DataGrid.ItemSource當我使用ObservableCollection<T>進行綁定?

我使用以下代碼將ObservableCollection<T>DataGrid綁定。

public partial class MainWindow : INotifyPropertyChanged 
{ 
    public MainWindow() 
    { 
     DataContext = this; 
     InitializeComponent(); 

     CalcObservable = 
      DatabaseQueries.ShiftInputSourceObserv(SelectedEmployee.Key, DateFilter); 

     MyDataGrid.ItemsSource = CalcObservable; 
    } 

    public ObservableCollection<CalcTable> CalcObservable { get; set; } 
      = new ObservableCollection<CalcTable>(); 
} 

這是從數據庫中獲取數據的功能,

internal class DatabaseQueries 
{ 
    public static ObservableCollection<CalcTable> ShiftInputSourceObserv(int staffNo, DateTime date) 
    { 
     using (DatabaseDataContext dataContext = new DatabaseDataContext(MainWindow.InstanceConnectionString)) 
     { 
      return new ObservableCollection<CalcTable> 
        (dataContext.CalcTables.Where(
         p => p.Staff_No == staffNo && 
         p.Year_No == date.Year && 
         p.Month_No == date.Month) 
         .OrderBy(p => p.Column_Index)); 
     } 
    } 
} 

然後我用一個ComboBox改變事件來更新ObservableCollection<T>SelectedEmployee.Key綁定到ComboBox和改變被選擇後,所選擇的員工:

private void NumbersComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
     CalcObservable = 
     DatabaseQueries.ShiftInputSourceObserv(SelectedEmployee.Key, DateFilter); 

     MyDataGrid.ItemsSource = CalcObservable; 
} 

我的印象是,改變ObservableCollection<T>將更新,而無需再次使用MyDataGrid.ItemsSource = CalcObservable;下?

感謝您的幫助。

+0

這不是一個新的實例嗎? – Ron

+0

而不是在'NumbersComboBox_SelectionChanged'中分配'CalcObservable',嘗試清除已有的集合,並將'DatabaseQueries.ShiftInputSourceObserv'的返回值中的項添加到現有集合(即'CalcObservable') –

+0

'ObservableCollection'將通知UI添加/刪除項目。但你正在做的是創建一個新實例 – Pikoh

回答

3

我使用下面的代碼綁定ObservableCollection<T>DataGrid ...

不,你不綁定。您將ItemsSource屬性設置爲您的CalcObservable屬性的值。

你然後在NumbersComboBox_SelectionChanged事件處理程序的CalcObservable屬性設置爲ObservableCollection<T>。這不會以某種方式自動更新DataGridItemsSource屬性。

如果你真的做綁定CalcObservable屬性,你可以刷新DataGrid前提是你的類實現了INotifyPropertyChanged接口,並且在該CalcObservable setter方法提高PropertyChanged事件:

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    public MainWindow() 
    { 
     DataContext = this; 
     InitializeComponent(); 

     CalcObservable = DatabaseQueries.ShiftInputSourceObserv(SelectedEmployee.Key, DateFilter); 
     MyDataGrid.SetBinding(ComboBox.ItemsSourceProperty, new Binding(nameof(CalcObservable)) { Source = this }); 
    } 

    private ObservableCollection<CalcTable> _calcObservable = new ObservableCollection<CalcTable>(); 
    public ObservableCollection<CalcTable> CalcObservable 
    { 
     get { return _calcObservable; } 
     set { _calcObservable = value; OnPropertyChanged(nameof(CalcObservable)); } 
    } 

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

的其他選項是清除ObservableCollection<T>的現有實例並向其添加新項目,而不是在每次要更新DataGrid時創建新的Collection。

+0

給我一點,我一直在努力實現這一點。我要誠實,它有點過頭了。您在數據網格上設置綁定的方式。 – KyloRen

+0

你是如何定義一個綁定*編程*。您可以在XAML標記中設置綁定:。但是,您應該*不*通過編程方式設置ItemsSource屬性,因爲那樣您就清​​除了您在XAML標記中定義的綁定。 – mm8

+0

我已經解決了評論的問題,但您的答案非常有趣。如您所知,您只能使用一個'OnPropertyChanged'方法,並且您顯示的方法不允許我的其他'OnPropertyChanged'屬性工作。你爲什麼這樣設置ObservableCollection ?這是不是老辦法做到這一點,作爲一個ObservableCollection 自動實現'INotifyPropertyChanged'?我已經提出了你所展示的幫助,但我想更多地理解這個答案。 – KyloRen