• 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;
                }
            }
        }
  • 相关阅读:
    MySQL动态游标
    扩展JS Date对象时间格式化功能
    Spring+ibatis动态管理数据源
    Spring在web应用中获得Bean的方法
    访问iis时需要输入服务器用户名密码
    sql08 语句修改标识列数据
    在浏览器选项卡上面追加网站Logo图
    'WebForm_PostBackOptions' 未定义 webForm_PostBackOptions is undefined
    pylot是一款开源的web性能测试工具
    在RedHat上安装gcc,java 和 eclipse-rcp
  • 原文地址:https://www.cnblogs.com/maigc249/p/5244694.html
Copyright © 2020-2023  润新知