有人可以告诉我如何在ObjectListView中继续选择吗?
我在控件中有一个对象列表,我从数据库中收到这些对象。用户选择一个,然后点击“刷新”(以便再次从数据库中检索所有项目)。选择是“跳跃”,但我希望它保留在用户选择的对象上。
我必须通过唯一ID来比较对象,这样数据库中的排序或新对象不得影响用户选择。
提前致谢。
答案 0 :(得分:2)
这是我的解决方案(根据Barry Guvenkaya的回答)。我认为
我的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,这是个好消息!如果实现GetHashCode
和Equals
,则可以清除列表并通过传递旧列表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();
}
}