在ObjectListView中保存和恢复选择

时间:2014-07-30 13:44:46

标签: c# objectlistview

有人可以告诉我如何在ObjectListView中继续选择吗?

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

我必须通过唯一ID来比较对象,这样数据库中的排序或新对象不得影响用户选择。

提前致谢。

4 个答案:

答案 0 :(得分:2)

这是我的解决方案(根据Barry Guvenkaya的回答)。我认为

  1. 可以选择多个项目(通过鼠标或键盘)
  2. 对象ID不存储在OLVListItem的列中,但是在对象内部(可以隐藏列,它们的顺序可以不同)。
  3. 我的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;
            }
     }
    

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

答案 1 :(得分:1)

<强>问题:

清除对象并再次构建列表后,无论是否将变量保留在变量中,所选项目都会消失。因为要保留此信息,必须将所选项的变量声明为动态附加到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)复杂性。这意味着如果您有数千条记录,它可能会减慢您的应用程序。

答案 2 :(得分:0)

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

您的代码应尽可能维护数据中的原始对象,并在需要时进行更新。如果清除所有对象并重新创建新对象,则会丢失选择并被迫诉诸其他方式来记住选择。

答案 3 :(得分:0)

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

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