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