我正在使用WPF,并尝试遵循MVVM模式。我们的团队已决定使用Xceed DataGrid控件,并且我有一些困难使其适合MVVM模式。

我必须满足的一个要求是,我需要知道何时用户更改网格上的列过滤器。我知道,DataGrid控件的最新版本具有为此提出的事件,但是不幸的是,我必须使用旧版本的控件版本。

搜索一段时间后,我发现 邮政。它说我需要将一个InotifyCollectionChanged处理程序挂钩到每个可能的过滤器列表中。这起作用了,但它还说我需要在网格的行更改时解开处理程序。

当我在页面的CodeBehind中明确设置行源时,我能够使它起作用(并且在ModelView中使用直接引用在ModelView中的第一次尝试中 喘气!)

不过,我遇到的第一个问题是如何在不包含ViewModel的代码中的逻辑的情况下执行此操作。我的解决方案是扩展DataGridControl类并添加以下代码:

    private IDictionary<string, IList> _GridFilters = null;
    public MyDataGridControl() : base()
    {
        TypeDescriptor.GetProperties(typeof(MyDataGridControl))["ItemsSource"].AddValueChanged(this, new EventHandler(ItemsSourceChanged));
    }

    void ItemsSourceChanged(object sender, EventArgs e)
    {
        UnsetGridFilterChangedEvent();
        SetGridFilterChangedEvent();
    }

    public void SetGridFilterChangedEvent()
    {
        if (this.ItemsSource == null)
            return;

        DataGridCollectionView dataGridCollectionView = (DataGridCollectionView)this.ItemsSource;

        _GridFilters = dataGridCollectionView.AutoFilterValues;

        foreach (IList autofilterValues in _GridFilters.Values)
        {
            ((INotifyCollectionChanged)autofilterValues).CollectionChanged += FilterChanged;
        }
    }

    /*TODO: Possible memory leak*/
    public void UnsetGridFilterChangedEvent()
    {
        if (_GridFilters == null)
            return;

        foreach (IList autofilterValues in _GridFilters.Values)
        {
            INotifyCollectionChanged notifyCollectionChanged = autofilterValues as INotifyCollectionChanged;

            notifyCollectionChanged.CollectionChanged -= FilterChanged;
        }

        _GridFilters = null;
    }

这使我遇到了下一个问题;我很确定,当调用了QuateSourcechange的方法时,AutoFilterValues的集合已经更改,因此我无法有效地解开处理程序。

我假设这是正确的吗?谁能想到一种更好的方法来管理这些处理程序,同时仍然让我将这些功能封装在我的扩展类中?

抱歉,帖子的长度,并提前感谢您的帮助!

-Funger

有帮助吗?

解决方案

您是正确的,当时自动浮雕已经更改了,因此您将解开错误的处理程序,从而导致内存泄漏。

解决方案非常容易。确切地做您在做的事情,但要使用 List<IList> 而不仅仅是引用自动滤波器:

private List<IList> _GridFilters;

并使用 ToList() 为了制作您设置处理程序的过滤器的副本:

_GridFilters = dataGridCollectionView.AutoFilterValues.Values.ToList();

由于_gridfilters现在是 List<IList>, ,您还必须更改循环:

foreach(IList autofilterValues in _GridFilters) 
  ...

之所以如此,是因为将旧过滤器列表的实际列表复制到_gridfilters中,而不是简单地引用自动式值属性。

这是一种适用于许多情况的不错的通用技术。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top