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;
            }
        }
    }
时间: 2024-10-14 07:18:26

DataGrid 刷新选中问题的相关文章

【转】WPF DataGrid 获取选中的当前行某列值

方法一:DataRowView mySelectedElement = (DataRowView)dataGrid1.SelectedItem; string result = mySelectedElement.Row[0]ToString(); 方法二:var a = this.dataGrid1.SelectedItem; var b = a as DataRowView;string result = b.Row[0].ToString(); [转]WPF DataGrid 获取选中的当

EsayUI datagrid 刷新问题

最近使用esayui 实现前台界面,在对父页面中datagrid列表项进行操作后,如果操作子页面是依附于父页面弹出的窗体,那么调用parent.$("#grid").datagrid('reload')可以正常的刷新datagrid列表,但是如果子页面是依附于父页面的上级添加的一个tab标签页的话,那么调用parent.$("#grid").datagrid('reload')就不能刷新,这是因为此时的parent是子页面的父级发上一级,所以不能找到$("

elementui导航栏刷新选中问题

获取地址栏中的路由,设置elementui中的导航栏选中状态 <el-menu :default-active="activerouter" class="el-menu-vertical-demo" background-color="#13141f" text-color="#fff" active-text-color="#fff" router style="height:100%&

easyui datagrid checkbox选中事件

$('#grid_Order').datagrid({       onCheck: function(index, data) { //alert(data[0]);               //alert(index );               $("#ChangeCore_order_id").html(data[0]);//赋值 赋安装工单id 换芯 维修 用               $("#Repair_order_id").html(dat

WPF DataGrid 获取选中的当前行某列值

方法一: DataRowView mySelectedElement = (DataRowView)dataGrid1.SelectedItem; string result = mySelectedElement.Row[0]ToString(); 方法二: var a = this.dataGrid1.SelectedItem; var b = a as DataRowView; string result = b.Row[0].ToString();

easyui datagrid 的分页刷新按钮

datagrid  刷新bug: 情形: 当用户A,B  同时操作 datagrid时(记录1,记录2.记录3).如果A如果删除记录1,  B此时已选中了记录1 ,记录2 , 这时B点击分页中的刷新按钮后,记录1不可见.但是getchecked  会发现选中的是2条记录(记录1 记录2 ) ,而不是一条记录2. 一种办法: 再点击刷新按钮的时候.清除所有选中的行. easyui ui 1.4.2 jquery.easyui.min.js _5d4.pagination({ total: (opt

Silverlight获取DataGrid选中的行数据

注意触发的事件为:CurrentCellChanged后台代码: /// <summary> /// 获取datagrid当前选中的单元格数据 /// 如果绑定的数据源为实体的话默认选中的当前记录为一条实体 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void dgca

easyui datagrid 学习 (一)

注意:当使用谷歌浏览器时!需要 设置style="overflow:hidden",这样则可以去掉滚动条!(该样式添加到layout上!) fit:属性 自动填父容器, border:属性 默认为true,设置为false时!去掉边框! <body>    <table id="dg"></table>    <script type="text/javascript">        $(func

datagrid 使用时遇到的问题

目前使用的wpf的datagrid还存在两个问题没有搞定,一个是datagrid的选中事件,另一个则是鼠标滚轮滚动时,datagrid的行间距发生变化. 第一个问题的解决方案:设置datagrid的属性SelectionUnit="Cell",这样每次选中就只是一个单元格,需要设置 <DataGrid.CellStyle> <Style TargetType="DataGridCell"> <Style.Triggers > &l