实现INotifyPropertyChanged null的PropertyChanged事件的类

时间:2018-04-20 19:02:40

标签: c# winforms

我在这里看到这个问题很多,但它总是WPF,我使用的是WinForms。

我有一个实现INotifyPropertyChanged的类,当在其中一个属性setter中调用OnPropertyChanged时,PropertyChanged事件对象始终为null,因此永远不会引发该事件。

public abstract class ProxyScraperSiteBase : IProxyScraperSite, INotifyPropertyChanged
{

    private int scrapedCount;

    public event PropertyChangedEventHandler PropertyChanged;
    public event EventHandler<PageScrapedEventArgs> PageScraped;

    public string SiteName { get; set; }
    public List<Proxy> ScrapedProxies { get; set; } = new List<Proxy>();
    public int ScrapedCount {
        get
        {
            return this.scrapedCount;
        }
        set
        {
            this.scrapedCount = value;
            OnPropertyChanged();
        }
    }

    public abstract Task ScrapeAsync(IWebDriver driver, PauseOrCancelToken pct = null);

    private void OnPropertyChanged([CallerMemberName] String propertyName = "")
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    protected void OnPageScraped(List<Proxy> proxies)
    {
        if (PageScraped != null)
        {
            PageScraped(this, new PageScrapedEventArgs(proxies));
        }
    }
}

设置绑定

public partial class ProxyScraperForm : Form
{

    private BindingList<IProxyScraperSite> sites = new BindingList<IProxyScraperSite>();

    public ProxyScraperForm()
    {
        InitializeComponent();

        sites.Add(new ProxyScraperSiteUsProxyOrg());

        ScraperDataGridView.DataSource = sites;
    }

    private void ScrapeButton_Click(object sender, EventArgs e)
    {
        foreach (var site in sites)
        {
            Task.Run(async () =>
            {

                site.PageScraped += Site_PageScraped;
                var driver = SeleniumUtility.CreateDefaultFirefoxDriver();
                await site.ScrapeAsync(driver);
                driver.Quit();
            });
        }
    }

    private void Site_PageScraped(object sender, PageScrapedEventArgs e)
    {
        ScraperDataGridView.BeginInvoke(new Action(() =>
        {
            ((IProxyScraperSite)sender).ScrapedCount += e.Proxies.Count;
        }));
    }
}

1 个答案:

答案 0 :(得分:2)

问题是您绑定到IProxyScraperSite,但该接口未实现INotifyPropertyChanged。绑定只知道接口而不是具体类,所以它不知道INotifyPropertyChanged已经实现。修复很简单,将INotifyPropertyChanged移到IProxyScraperSite界面:

public interface IProxyScraperSite : INotifyPropertyChanged
{
    ...
}

这将允许您的BindingList订阅INotifyPropertyChanged事件,因为它现在可以看到绑定对象实现它。