DataGrid 刷新选中问题

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DataGrid 刷新选中问题相关的知识,希望对你有一定的参考价值。

  背景:在项目中遇到了这样的问题,使用的DataGrid需要默认选中第一条数据,即数据加载后,无需用户点击,即可默认选中一项,并且,DataGrid支持筛选操作,需要完成这样的功能,数据源中的数据项的某些属性更新时,需要刷新UI,并且需要保持当前的多选项。

  问题:上面的背景中提到了两个问题,一是需要默认选中第一项;二是DataGrid相关的视图进行刷新时需要保持上次的多选项。默认选中第一项可以在数据加载完成后使用一个双向绑定完成,而保持上次的多选项,DataGrid提供了一个内部属性用来控制,即为IsSynchronizedWithCurrentItem,其值为false时,会保持上次的多选项,但此时设置当前选中的。这样只可以实现,便却要判断每一个当前选中项可以会空的场景,并及时的设置当前选中项为视图中的第一项,太过复杂,容易出错。

  解决方案:自定一个集合及所使用的视图类,在视图类中判断当前选中项为空且视图列表不为空的情况下,设置当前选中项为列表中第一项,否则为需要保持多选项的情况,即需要控件的IsSynchronizedWithCurrentItem=false来保证,在视图中设置默认选中项时又需要设置IsSynchronizedWithCurrentItem=true才能保持视图中的更改可以及时的刷新到UI上去。因此需要做好的两种情况的判断,从而正确切换IsSynchronizedWithCurrentItem,保证UI的正确性。

  实现:数据的筛选需要重新Filter一次,需要调用视图的Refresh操作,通过分析源码,分析出刷新的过程,实现的示例图可参照下图:

  注意:IsSynchronizedWithCurrentItem主要是用来同步当前选中项,在多UI使用同一数据源时可以同步当前选中项,但这里的实现并不支持,因为需要视图类与UI耦合。

  技术分享

  实现源码:

public class CustomCollection<T> : ObservableCollection<T>, ICollectionViewFactory
    {
        public CustomCollection(Selector selector)
        {
            _selector = selector;
        }

        private readonly Selector _selector;

        public ICollectionView CreateView()
        {
            return new MyView(this, _selector);
        }
    }

    public class MyView : ListCollectionView
    {
        public MyView(IList list, Selector selector)
            : base(list)
        {
            if (null != selector)
            {
                _selector = selector;
                _dgSynchronized = _selector.IsSynchronizedWithCurrentItem;
            }
        }

        private readonly Selector _selector;
        private readonly bool? _dgSynchronized;

        private object _preCurrentItem = null;
        protected override void RefreshOverride()
        {
            _preCurrentItem = CurrentItem;
            base.RefreshOverride();
        }

        protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
        {
            if (null != _selector)
            {
                //some scen, CurrentItem can be set by Func before this method, avoid this
                if (_preCurrentItem != CurrentItem)
                    SetCurrent(null, -1);

                if (null == CurrentItem && InternalCount > 0)
                {
                    _selector.IsSynchronizedWithCurrentItem = true;
                    SetCurrent(InternalList[0], 0);
                }
                else
                    _selector.IsSynchronizedWithCurrentItem = false;
            }

            base.OnCollectionChanged(args);
        }

        protected override void OnCurrentChanged()
        {
            base.OnCurrentChanged();

            if (null != _selector)
            {
                _selector.IsSynchronizedWithCurrentItem = _dgSynchronized;
            }
        }
    }

 

以上是关于DataGrid 刷新选中问题的主要内容,如果未能解决你的问题,请参考以下文章

如何用代码选中datagrid中的某一行

求助Easyui datagrid 的默认选中问题

当其 ItemsSource 更改时自动刷新 Datagrid

easy ui datagrid翻页刷新问题

在 Silverlight 中刷新 DataGrid

如何设置DataGrid的某些行不能被选中