实施InotifyPropertyChanged Null Property Changed事件的类



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

我有一个实现InotifyPropertychanged的类,当onPropertychanged在其中一个属性设置器中调用时,属性变化的事件对象始终是无效的,因此事件永远不会增加。

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

问题是您要绑定到IProxyScraperSite,但是该接口不实现INotifyPropertyChanged。绑定仅知道接口,而不是具体类,因此不知道已经实现了INotifyPropertyChanged。修复程序很简单,将INotifyPropertyChanged移至IProxyScraperSite接口:

public interface IProxyScraperSite : INotifyPropertyChanged
{
    ...
}

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

最新更新