使用FileSystemWatcher动态更改组合框中的项

本文关键字:组合 FileSystemWatcher 动态 使用 | 更新日期: 2023-09-27 18:02:13

好的,所以我尝试使用FileSystemWatcher来监视目录中的更改,然后动态更改组合框中的项。我的populateCb()方法在加载用户控件时开始工作。我在监视器更改事件中添加了一个断点,当我更改目录的内容时,它会中断。所以我知道事件正在被触发,watcher_Changed方法正在被调用。但是我的组合框的内容没有改变……我做错了什么?

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

使用FileSystemWatcher动态更改组合框中的项

最简单的解决方案是在更改List<string> emails之前将ItemSource设置为null

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。它是同一个物体。List<string>没有能力通知WPF的绑定基础结构对其元素的更改。所以清除项目,读取它们是完全不可见的组合框。而不是设置ItemSource = null,然后重新设置它,通知组合框的变化。

一个可能的(可能是更好的选择)是将您的List更改为具有通知更改能力的ObservableCollection