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

 

转载于:https://www.cnblogs.com/maigc249/p/5244694.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值