当它们是自定义对象时更新列表框项目 [英] Updating Listbox Items when they are custom Objects

查看:90
本文介绍了当它们是自定义对象时更新列表框项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在表单上有一个ListBox.

当我向ListBox添加新项目时,我正在添加名为Query的自定义类.在Query类中,我重写了ToString()方法以显示Name属性.

当我添加所有新项目时,这非常有用.它们已正确存储在ListBox中并正确显示.

我尝试重命名Query时遇到了问题.我有一个使用的ContextMenuStrip和一个简单的InputBox来允许用户重命名该项目.它可以正常工作并重命名QueryName属性,但是,它不会更新ListBox中显示的内容.

示例:
当我单击添加"按钮时,它将添加一个名为新数据集"的新Query.然后,用户右键单击该项目,然后单击重命名"按钮.这会加载一个InputBox,要求他们输入新名称,然后将原始名称加载到InputBox中.

用户输入新名称,然后按Enter,然后运行:

I have a ListBox on a form.

When I add a new item to the ListBox, I am adding a custom class called Query. In the Query class I have overridden the ToString() method to display the Name property.

This works great when I add all of the new items. They are stored correctly in the ListBox and they are displayed correctly.

My problem comes when I try to rename a Query. I have a ContextMenuStrip that I use and a simple InputBox to allow the user to rename the item. It works properly and renames the Name property of the Query, however, it does not update what is displayed in the ListBox.

Example:
When I click the "Add" button, it adds a new Query with the name "New Dataset". Then, the user right-clicks on that item and they click the "Rename" button. This loads up an InputBox asking them to enter a new name and loads the original name into the InputBox.

The user enters a new name hits enter and I run:

//In C#
((MyMDX.Query)lboDataSets.SelectedItem).Name = newName;


'In VB.NET
CType(lboDataSets.SelectedItem, myMDX.Query).Name = newName



这确实会更新SelectedItem以反映新名称,但是ListBoxListBox中显示的值仍然是"New Dataset".

我已经尝试运行lboDataSets.Invalidate()lboDataSets.Refresh()lboDataSets.BeginUpdate()/lboDataSets.EndUpdate,并且尝试更改lboDataSets.SelectedValue(),并且没有任何更新显示的值.

那么,如何获取显示的值进行更新?

[更新]
没有人有答案吗?我可以通过将Query存储为临时对象,然后删除原始项目,然后将temp对象插入到原始位置来伪造它,但这似乎比实际解决方案更可行. />
吕克:
我在主线程上...创建了ListBox的那个主线程.因此,我此时无需使用Invoke.我已经尝试过Invalidate(),但是就像您说的那样,它似乎是静态存储的,并且在基础数据更改时它也不会更改.我已经尝试了Invalidate()Refresh(),都没有一个人强制调用ToString()函数.



This does update the SelectedItem to reflect the new name, however, the displayed value of the Item in the ListBox is still "New Dataset".

I have tried running lboDataSets.Invalidate(), lboDataSets.Refresh(), lboDataSets.BeginUpdate()/lboDataSets.EndUpdate and I have tried changing lboDataSets.SelectedValue() and nothing updates the displayed value.

So, how can I get the displayed value to update?

[Update]
No one has an answer? I was able to fake it by storing the Query as a temporary object and then removing the original item, and inserting the temp object back into the original place, but that seems more like a work-around than an actual solution.

Luc:
I''m on the main thread...the one that the ListBox was created on. So, I don''t need to use Invoke at that point. And I''ve tried Invalidate(), but like you said, it seems to store the name statically and it doesn''t change when the underlying data changes. I''ve tried both Invalidate() and Refresh() and neither one forces a call back to the ToString() function.

推荐答案



显然,仅更改某些对象的名称(例如Query实例)不会导致ListBox自身更新,因为它们不是从Query实例到ListBox的前向连接;存在的唯一连接是向后的连接,ListBox知道它正在显示一些Query对象.

因此,您需要使用Invalidate()或Refresh()方法告诉ListBox需要完成的事情.但是,列表框是一个控件,这意味着您不能从自己喜欢的任何线程中触摸它.因此,您需要我在此处描述的Control.InvokeRequires/Control.Invoke模式 [
Hi,

clearly just changing the Name of some object (say a Query instance) does not cause a ListBox to update itself, as their is no forward connection from the Query instance to the ListBox; the only connection that exists is a backward one, the ListBox knowing it is showing some Query objects.

So you need to tell the ListBox something needs to be done, using the Invalidate() or the Refresh() methods. However a ListBox is a Control, which means you are not allowed to touch it from just any thread you like. So you need the Control.InvokeRequires/Control.Invoke pattern which I described here[^].

If you are sure you''re on the wrong thread, and since you don''t need to pass any parameters, it could be simplified to
lboDataSets.Invoke(new MethodInvoker(delegate() {
    lboDataSets.Invalidate();
}));



:)



:)


Dim i As Integer
        i = ListBox1.SelectedIndex.ToString
        ListBox1.Items.RemoveAt(ListBox1.SelectedIndex.ToString)
        ListBox1.Items.Insert(i, TextBox3.Text)


这篇关于当它们是自定义对象时更新列表框项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆