【问题标题】:Datagrid does not maintain sort when the items are updated更新项目时 Datagrid 不维护排序
【发布时间】:2011-11-10 10:22:36
【问题描述】:

我有一个很好的 WPF DataGrid 绑定到对象集合。一切正常,当任何对象的属性更改时,网格都会更新。问题是更新发生时行没有重新排序,然后排序不再有效。

知道如何解决这个问题吗?

提前致谢。

编辑:这就是我绑定 DataGrid 的方式:

<Controls:DataGrid MinHeight="300" MinWidth="300" ItemsSource="{Binding Data}" AutoGenerateColumns="True">

public class MainWindowViewModel
{ 
    public ObservableCollectionMultiThread<StockViewModel> Data { get; private set; }
} 

public class ObservableCollectionMultiThread<T> : ObservableCollection<T>
{
    // Override the event so this class can access it
    public override event System.Collections.Specialized.NotifyCollectionChangedEventHandler CollectionChanged;

    protected override void OnCollectionChanged(System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        // Be nice - use BlockReentrancy like MSDN said
        using (base.BlockReentrancy())
        {
            System.Collections.Specialized.NotifyCollectionChangedEventHandler eventHandler = this.CollectionChanged;
            if (eventHandler == null)
                return;

            Delegate[] delegates = eventHandler.GetInvocationList();
            // Walk thru invocation list
            foreach (System.Collections.Specialized.NotifyCollectionChangedEventHandler handler in delegates)
            {
                DispatcherObject dispatcherObject = handler.Target as DispatcherObject;
                // If the subscriber is a DispatcherObject and different thread
                if (dispatcherObject != null && dispatcherObject.CheckAccess() == false)
                {
                    // Invoke handler in the target dispatcher's thread
                    dispatcherObject.Dispatcher.Invoke(DispatcherPriority.DataBind, handler, this, e);
                }
                else // Execute handler as is
                    handler(this, e);
            }
        }
    }
}

PD:我使用的是 2008 年 10 月 CTP 的 DataGrid,因为我使用的是 Net 3.5

【问题讨论】:

  • 你能告诉我们你是如何加载和绑定数据的吗?您知道根据您的操作方式,您应该重新应用排序标准吗?
  • 啊,这是我第一次使用 WPF DataGRid,我不知道。我正在使用一个特殊的 ObservableCollection 来绑定,它允许来自其他线程的更新。我将尝试使用普通集合并更新问题,谢谢。

标签: c# .net wpf sorting datagrid


【解决方案1】:

通常 WPF 上的控件不响应项目版本。我使用这个类作为网格的来源:

using System;
using System.Collections;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Windows.Data;
using System.Windows.Threading;

namespace StockCrawler
{
public class AutoRefreshListCollectionView : ListCollectionView
{

    public AutoRefreshListCollectionView(IList list)
        : base(list)
    {
        this.SubscribeSourceEvents(list, false);
    }

    private void Item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {

        bool refresh = false;

        foreach (SortDescription sort in this.SortDescriptions)
        {
            if (sort.PropertyName == e.PropertyName)
            {
                refresh = true;
                break;
            }
        }

        if (!refresh)
        {
            foreach (GroupDescription group in this.GroupDescriptions)
            {
                PropertyGroupDescription propertyGroup = group as PropertyGroupDescription;

                if (propertyGroup != null && propertyGroup.PropertyName == e.PropertyName)
                {
                    refresh = true;
                    break;
                }
            }
        }

        if (refresh)
        {
            if (!this.Dispatcher.CheckAccess())
            {
                // Invoke handler in the target dispatcher's thread
                this.Dispatcher.Invoke((Action)this.Refresh); 
            }
            else // Execute handler as is
            {
                this.Refresh();                 
            }
        }
    }

    private void Source_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.Action == NotifyCollectionChangedAction.Add)
        {
            this.SubscribeItemsEvents(e.NewItems, false);
        }
        else if (e.Action == NotifyCollectionChangedAction.Remove)
        {
            this.SubscribeItemsEvents(e.OldItems, true);
        }
        else
        {
            // TODO: Support this

        }
    }

    private void SubscribeItemEvents(object item, bool remove)
    {
        INotifyPropertyChanged notify = item as INotifyPropertyChanged;

        if (notify != null)
        {
            if (remove)
            {
                notify.PropertyChanged -= this.Item_PropertyChanged;
            }
            else
            {
                notify.PropertyChanged += this.Item_PropertyChanged;
            }
        }
    }

    private void SubscribeItemsEvents(IEnumerable items, bool remove)
    {
        foreach (object item in items)
        {
            this.SubscribeItemEvents(item, remove);
        }
    }

    private void SubscribeSourceEvents(object source, bool remove)
    {
        INotifyCollectionChanged notify = source as INotifyCollectionChanged;

        if (notify != null)
        {
            if (remove)
            {
                notify.CollectionChanged -= this.Source_CollectionChanged;
            }
            else
            {
                notify.CollectionChanged += this.Source_CollectionChanged;
            }
        }

        this.SubscribeItemsEvents((IEnumerable)source, remove);
    }
}
}

【讨论】:

    猜你喜欢
    • 2014-08-28
    • 1970-01-01
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-05
    • 1970-01-01
    • 2012-05-01
    相关资源
    最近更新 更多