2015-07-10 36 views
0

好的,所以我試圖使用FileSystemWatcher監視目錄中的更改,然後動態更改組合框中的項目。我的populateCb()方法最初在用戶控件加載時起作用。並且當我改變目錄的內容時,在觀察者改變的事件內部添加了一個斷點。所以我知道這些事件正在被觸發,並且正在調用watcher_Changed方法。但我的組合框的內容不會改變......我做錯了什麼?使用FileSystemWatcher動態更改組合框中的項目

public partial class HtmlViewer : UserControl 
{ 
    private List<string> emails = new List<string>(); 
    FileSystemWatcher watcher = new FileSystemWatcher("emailTemplates", "*.msg"); 
    public HtmlViewer() 
    { 
     InitializeComponent(); 
     populateCb(); 
     watcher.Changed += watcher_Changed; 
     watcher.Created += watcher_Changed; 
     watcher.Deleted += watcher_Changed; 
     watcher.Renamed += watcher_Changed; 
     watcher.EnableRaisingEvents = true; 

    } 

    void watcher_Changed(object sender, FileSystemEventArgs e) 
    { 
     this.Dispatcher.Invoke((Action)(() => 
      { 
       populateCb(); 
      } 
      )); 

    } 
    private void populateCb() 
    { 
     emails.Clear(); 
     foreach(var file in Directory.EnumerateFiles("emailTemplates", "*.msg", SearchOption.AllDirectories)) 
     { 
      emails.Add(file); 
     } 
     emailSelector.ItemsSource = emails; 
    } 
} 
+1

不知道,但也許你需要設置的ItemSource爲空在populateCb方法作爲一線。 (或使用ObservableCollection) – Steve

+0

工作!謝謝!這太奇怪了,爲什麼不再次將項目源設置爲超過之前的值?我將不得不考慮ObservableCollections,這聽起來像是正確的解決方案。無論如何@Steve,你應該添加一個答案,以便我可以將這個問題標記爲已回答。 –

+1

因爲您沒有設置新的項目源。它是同一個對象。您已更改其內容,但對象(列表)無法通知更改。設置ItemSource = null,然後再次將其重置爲同一對象,通知更改的組合框綁定代碼 – Steve

回答

1

最簡單的辦法是改變List<string> emails

private void populateCb() 
{ 
    emailSelector.ItemsSource = null; 
    emails.Clear(); 
    foreach(var file in Directory.EnumerateFiles("emailTemplates", "*.msg", SearchOption.AllDirectories)) 
    { 
     emails.Add(file); 
    } 
    emailSelector.ItemsSource = emails; 
} 

沒有它你是不是改變了以前的ItemSource之前設置ItemSource爲null。它是同一個對象。 List<string>沒有能力通知WPF綁定基礎設施對其元素的更改。因此清除項目,讀取它們對於ComboBox來說是完全不可見的。相反,設置ItemSource = null,然後再次重置它通知組合框的變化。

一種可能(也可能是更好的選擇)是你的列表更改爲ObservableCollection有到notifiy能力改變

相關問題