Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/273.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在ObjectListView中保存和还原所选内容_C#_Objectlistview - Fatal编程技术网

C# 在ObjectListView中保存和还原所选内容

C# 在ObjectListView中保存和还原所选内容,c#,objectlistview,C#,Objectlistview,有人能告诉我如何保持选择吗 我的控件中有一个从数据库接收的对象列表。用户选择一个,然后点击“刷新”(以便再次从数据库检索所有项目)。选择是“跳跃”,但我希望它保持在用户选择的对象上 我必须通过对象的唯一id来比较对象,以便排序或数据库中的新对象不会影响用户选择 提前感谢。问题: 清除对象并再次构建列表后,所选项目将消失,无论是否将其保留在变量中。因为要保留此信息,所选项目的变量必须声明为动态附加到OLV控件的变量。这就是为什么清除列表后,变量将无法保留所选项目的原因 关于解决方法: 我有一个解决

有人能告诉我如何保持选择吗

我的控件中有一个从数据库接收的对象列表。用户选择一个,然后点击“刷新”(以便再次从数据库检索所有项目)。选择是“跳跃”,但我希望它保持在用户选择的对象上

我必须通过对象的唯一id来比较对象,以便排序或数据库中的新对象不会影响用户选择


提前感谢。

问题:

清除对象并再次构建列表后,所选项目将消失,无论是否将其保留在变量中。因为要保留此信息,所选项目的变量必须声明为动态附加到OLV控件的变量。这就是为什么清除列表后,变量将无法保留所选项目的原因

关于解决方法:

我有一个解决这个问题的方法。大多数人可能会考虑实现
objectListViewUserList.SelectedItem
属性,但该属性存在一些问题。这与某些原因不一致。因此,对于我的解决方法,我将介绍这个属性
objectListViewUserList.MouseMoveHitTest
。这听起来像是一个测试变量,但它的工作原理就像一个符咒

假设:

此外,为了实现此解决方案,假设第一列是ID列

解决方法:

这是解决办法。在click事件中,将第一列的文本信息保留在公共字符串中

    private void objectListViewUserList_Click(object sender, EventArgs e)
    {
        if (objectListViewUserList.MouseMoveHitTest.Item != null)
            selectedItemText = objectListViewUserList.MouseMoveHitTest.Item.Text;
        else
            selectedItemText = "";
    }
在我的应用程序中,我使用
fillOnlineUsers
方法刷新OLV控件。这是武断的。它可以是任何方法。在我的应用程序中,此方法与计时器配合使用。每次刷新后,我通过在新列表中搜索ID来选择项目

    public void fillOnlineUsers()
    {
        objectListViewUserList.ClearObjects();
        objectListViewUserList.AddObjects(onlineUsers);
        objectListViewUserList.BuildList();
        if (selectedItemText != "")
        {
            foreach (OLVListItem olvi in objectListViewUserList.Items)
                if (olvi.Text == selectedItemText)
                    olvi.Selected = true;
        }
    }
此解决方案具有O(n)复杂性。这意味着,如果您有数千条记录,它可能会降低您的应用程序速度。

这是我的解决方案(基于Barry Guvenkaya的答案)。我想

  • 可以选择多个项目(通过鼠标或键盘)
  • 对象ID不存储在OLVListItem的列中,而是存储在对象内部(列可以隐藏,它们的顺序可以不同)
  • My
    Refresh()
    函数:

    PushSelected();
    objectListView.SetObjects(...);
    PopSelected();
    
    使用以下命令保存和还原所选内容:

    private List<Guid> selected;   // Keeping the ID's of selected objects
    
    public void PushSelected()
    {
        // Value of SelectedList can be get using
        // objectListView.SelectedObjects
    
        selected.Clear();
        foreach (MyObject r in SelectedList)  
            selected.Add(r.id);
    }
    
    public void PopSelected()
    {
        D.DeselectAll();
    
        if (selected.Count != 0)
            for (int i = 0; i < objectListView.Items.Count; i ++)
            {
                OLVListItem item = (OLVListItem)objectListView.Items[i];
                Guid g = ((MyObject)item.RowObject).id;
                if (selected.Contains(g))
                    item.Selected = true;
            }
     }
    
    已选择私有列表;//保留选定对象的ID
    已选定的公共空间()
    {
    //SelectedList的值可以使用
    //objectListView.SelectedObject
    选中。清除();
    foreach(选定列表中的MyObject r)
    选中。添加(r.id);
    }
    已选定的公共void PopSelected()
    {
    D.取消选择全部();
    如果(已选择。计数!=0)
    for(int i=0;i

    当然,如果选择了所有项,此解决方案也有O(n)复杂度,甚至O(n*n)。

    如果使用ObjectListView的2.9.1版,只使用olv.SetObjects(YourDataObject) 现有选择将被保留,您不需要任何耗时的方法或变通方法来记住活动选择


    您的代码应该尝试维护数据中的原始对象。如果可能,请在需要时更新这些对象。如果清除所有对象并重新创建新对象,则会丢失选择,并被迫使用其他方法来记住选择。

    因此,从其他帖子中可以看出,您的记录似乎有一个Guid,这是个好消息!如果实现了
    GetHashCode
    Equals
    ,则可以通过传递旧列表
    olv.SelectedObjects.Cast().ToList()
    来清除列表并重新选择旧选择

    公共部分类表单1:表单
    {
    专用Guid _guid1;
    专用Guid _guid2;
    类MyClass
    {
    公共只读Guid;
    公共字符串密钥;
    公共字符串值;
    公共MyClass(Guid、字符串键、字符串值)
    {
    钥匙=钥匙;
    Guid=Guid;
    价值=价值;
    }
    公共覆盖int GetHashCode()
    {
    返回Guid.GetHashCode();
    }
    公共覆盖布尔等于(对象对象对象)
    {
    如果(obj是MyClass)
    返回此.Guid.Equals(((MyClass)obj.Guid);
    返回基数等于(obj);
    }
    }
    公共表格1()
    {
    初始化组件();
    olv.FullRowSelect=true;
    olv.HideSelection=false;
    _guid1=Guid.Parse(“026c90aa-7fb8-452d-b8bc-b42fd7bc0e7f”);
    _guid2=Guid.Parse(“85ea0ce0-da65-412f-8198-724c196342da”);
    olv.AddObjects(新[]
    {
    //将被更新的两个对象
    新MyClass(_guid1,“go”,“nuts”),
    新MyClass(_guid2,“lol”,“rly?”),
    //一个会破坏的物体
    新建MyClass(Guid.NewGuid(),“再见”,“再见”)
    });
    }
    私有void BtnRefreshObjects_单击(对象发送者,System.EventArgs e)
    {
    olv.BeginUpdate();
    //还记得以前的东西吗
    var oldSelection=olv.SelectedObjects.Cast().ToList();
    //将它们替换为新对象
    olv.ClearObjects();
    olv.AddObjects(
    新[]
    {
    //此对象保持不变
    新MyClass(_guid1,“go”,“nuts”),
    //此对象更改字段(但由于Guid的原因仍然是相同的记录)
    新的MyClass(_guid2,“omg2”,“omg3”),
    //这是一个新对象
    新建MyClass(Guid.NewGuid(),“omg5”,“omg6”)
    });
    //重置旧选择(即使它们是过时对象,但由于相等替代,选择仍有效)
    olv.SelectedObjects=oldSelection;
    olv.EndUpdate();
    }
    }
    
    正在“刷新”呼叫
    olv.Se
    
    public partial class Form1 : Form
    {
        private Guid _guid1;
        private Guid _guid2;
    
        class MyClass
        {
            public readonly Guid Guid;
            public string Key;
            public string Value;
    
    
            public MyClass(Guid guid, string key, string value)
            {
                Key = key;
                Guid = guid;
                Value = value;
            }
    
            public override int GetHashCode()
            {
                return Guid.GetHashCode();
            }
    
            public override bool Equals(object obj)
            {
                if (obj is MyClass)
                    return this.Guid.Equals(((MyClass) obj).Guid);
    
                return base.Equals(obj);
            }
        }
    
    
    
        public Form1()
        {
            InitializeComponent();
            olv.FullRowSelect = true;
            olv.HideSelection = false;
    
            _guid1 = Guid.Parse("026c90aa-7fb8-452d-b8bc-b42fd7bc0e7f");
            _guid2 = Guid.Parse("85ea0ce0-da65-412f-8198-724c196342da");
    
            olv.AddObjects(new []
            {
                //two objects that will be updated
                new MyClass(_guid1,"go","nuts"), 
                new MyClass(_guid2,"lol","rly?"),
    
                //one object that will disapear
                new MyClass(Guid.NewGuid(),"bye","bye")
            });
    
        }
    
        private void BtnRefreshObjects_Click(object sender, System.EventArgs e)
        {
            olv.BeginUpdate();
    
            //remember the old objects
            var oldSelection = olv.SelectedObjects.Cast<object>().ToList();
    
            //swap them for the new objects
            olv.ClearObjects();
            olv.AddObjects(
                new []
            {
                //This object stays the same
                new MyClass(_guid1,"go","nuts"), 
                //This object changes fields (but is still the same record due to Guid)
                new MyClass(_guid2,"omg2","omg3"),
                //This is a new object
                new MyClass(Guid.NewGuid(),"omg5","omg6")
            });
    
            //reset the old selection (even though they are stale objects the selection works because of Equality override)
            olv.SelectedObjects = oldSelection;
            olv.EndUpdate();
        }
    }