.net 如何让 ListBox 刷新其项目文本?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/61421/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I make a ListBox refresh its item text?
提问by OwenP
I'm making an example for someone who hasn't yet realized that controls like ListBoxdon't have to contain strings; he had been storing formatted strings and jumping through complicated parsing hoops to get the data back out of the ListBoxand I'd like to show him there's a better way.
我正在为那些还没有意识到控件ListBox不必包含字符串的人做一个例子;他一直在存储格式化的字符串并跳过复杂的解析圈以将数据从ListBox.
I noticed that if I have an object stored in the ListBoxthen update a value that affects ToString, the ListBoxdoes not update itself. I've tried calling Refreshand Updateon the control, but neither works. Here's the code of the example I'm using, it requires you to drag a listbox and a button onto the form:
我注意到,如果我有存储在一个对象ListBox,然后更新的影响的值ToString,则ListBox不会自动更新。我试过调用Refresh和Update控制,但都不起作用。这是我正在使用的示例代码,它要求您将一个列表框和一个按钮拖到表单上:
Public Class Form1
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
For i As Integer = 1 To 3
Dim tempInfo As New NumberInfo()
tempInfo.Count = i
tempInfo.Number = i * 100
ListBox1.Items.Add(tempInfo)
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For Each objItem As Object In ListBox1.Items
Dim info As NumberInfo = DirectCast(objItem, NumberInfo)
info.Count += 1
Next
End Sub
End Class
Public Class NumberInfo
Public Count As Integer
Public Number As Integer
Public Overrides Function ToString() As String
Return String.Format("{0}, {1}", Count, Number)
End Function
End Class
I thought that perhaps the problem was using fields and tried implementing INotifyPropertyChanged, but this had no effect. (The reason I'm using fields is because it's an example and I don't feel like adding a few dozen lines that have nothing to do with the topic I'm demonstrating.)
我认为问题可能出在使用字段并尝试实现INotifyPropertyChanged,但这没有效果。(我使用字段的原因是因为它是一个示例,我不想添加与我正在演示的主题无关的几十行。)
Honestly I've never tried updating items in place like this before; in the past I've always been adding/removing items, not editing them. So I've never noticed that I don't know how to make this work.
老实说,我以前从未尝试过像这样就地更新项目;过去我一直在添加/删除项目,而不是编辑它们。所以我从来没有注意到我不知道如何进行这项工作。
So what am I missing?
那么我错过了什么?
采纳答案by geno
BindingList handles updating the bindings by itself.
BindingList 自行处理更新绑定。
using System;
using System.ComponentModel;
using System.Windows.Forms;
namespace TestBindingList
{
public class Employee
{
public string Name { get; set; }
public int Id { get; set; }
}
public partial class Form1 : Form
{
private BindingList<Employee> _employees;
private ListBox lstEmployees;
private TextBox txtId;
private TextBox txtName;
private Button btnRemove;
public Form1()
{
InitializeComponent();
FlowLayoutPanel layout = new FlowLayoutPanel();
layout.Dock = DockStyle.Fill;
Controls.Add(layout);
lstEmployees = new ListBox();
layout.Controls.Add(lstEmployees);
txtId = new TextBox();
layout.Controls.Add(txtId);
txtName = new TextBox();
layout.Controls.Add(txtName);
btnRemove = new Button();
btnRemove.Click += btnRemove_Click;
btnRemove.Text = "Remove";
layout.Controls.Add(btnRemove);
Load+=new EventHandler(Form1_Load);
}
private void Form1_Load(object sender, EventArgs e)
{
_employees = new BindingList<Employee>();
for (int i = 0; i < 10; i++)
{
_employees.Add(new Employee() { Id = i, Name = "Employee " + i.ToString() });
}
lstEmployees.DisplayMember = "Name";
lstEmployees.DataSource = _employees;
txtId.DataBindings.Add("Text", _employees, "Id");
txtName.DataBindings.Add("Text", _employees, "Name");
}
private void btnRemove_Click(object sender, EventArgs e)
{
Employee selectedEmployee = (Employee)lstEmployees.SelectedItem;
if (selectedEmployee != null)
{
_employees.Remove(selectedEmployee);
}
}
}
}
回答by Brad Bruce
I use this class when I need to have a list box that updates.
当我需要一个更新的列表框时,我会使用这个类。
Update the object in the list and then call either of the included methods, depending on if you have the index available or not. If you are updating an object that is contained in the list, but you don't have the index, you will have to call RefreshItems and update all of the items.
更新列表中的对象,然后调用其中的任一方法,具体取决于您是否有可用的索引。如果要更新列表中包含的对象,但没有索引,则必须调用 RefreshItems 并更新所有项目。
public class RefreshingListBox : ListBox
{
public new void RefreshItem(int index)
{
base.RefreshItem(index);
}
public new void RefreshItems()
{
base.RefreshItems();
}
}
回答by Elton M
lstBox.Items[lstBox.SelectedIndex] = lstBox.SelectedItem;
回答by Jon
typeof(ListBox).InvokeMember("RefreshItems",
BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod,
null, myListBox, new object[] { });
回答by Quibblesome
Use the datasource property and a BindingSource object in between the datasource and the datasource property of the listbox. Then refresh that.
在列表框的数据源和数据源属性之间使用数据源属性和 BindingSource 对象。然后刷新那个。
updateadded example.
更新添加的示例。
Like so:
像这样:
Public Class Form1
Private datasource As New List(Of NumberInfo)
Private bindingSource As New BindingSource
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
MyBase.OnLoad(e)
For i As Integer = 1 To 3
Dim tempInfo As New NumberInfo()
tempInfo.Count = i
tempInfo.Number = i * 100
datasource.Add(tempInfo)
Next
bindingSource.DataSource = datasource
ListBox1.DataSource = bindingSource
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
For Each objItem As Object In datasource
Dim info As NumberInfo = DirectCast(objItem, NumberInfo)
info.Count += 1
Next
bindingSource.ResetBindings(False)
End Sub
End Class
Public Class NumberInfo
Public Count As Integer
Public Number As Integer
Public Overrides Function ToString() As String
Return String.Format("{0}, {1}", Count, Number)
End Function
End Class
回答by Ant
If you derive from ListBox there is the RefreshItem protected method you can call. Just re-expose this method in your own type.
如果您从 ListBox 派生,则可以调用 RefreshItem 保护方法。只需在您自己的类型中重新公开此方法即可。
public class ListBox2 : ListBox {
public void RefreshItem2(int index) {
RefreshItem(index);
}
}
Then change your designer file to use your own type (in this case, ListBox2).
然后更改您的设计器文件以使用您自己的类型(在本例中为 ListBox2)。
回答by JTIM
If you use a draw method like:
如果您使用如下绘制方法:
private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
e.DrawFocusRectangle();
Sensor toBeDrawn = (listBox1.Items[e.Index] as Sensor);
e.Graphics.FillRectangle(new SolidBrush(toBeDrawn.ItemColor), e.Bounds);
e.Graphics.DrawString(toBeDrawn.sensorName, new Font(FontFamily.GenericSansSerif, 14, FontStyle.Bold), new SolidBrush(Color.White),e.Bounds);
}
Sensor is my class.
传感器是我的班级。
So if I change the class Colorsomewhere, you can simply update it as:
因此,如果我在Color某处更改课程,您可以简单地将其更新为:
int temp = listBoxName.SelectedIndex;
listBoxName.SelectedIndex = -1;
listBoxName.SelectedIndex = temp;
And the Colorwill update, just another solution :)
并且Color将更新,只是另一个解决方案:)
回答by JTIM
It's little bit unprofessional, but it works. I just removed and added the item (also selected it again). The list was sorted according to "displayed and changed" property so, again, was fine for me. The side effect is that additional event (index changed) is raised.
这有点不专业,但它有效。我刚刚删除并添加了该项目(也再次选择了它)。该列表是根据“显示和更改”属性排序的,因此对我来说很好。副作用是会引发其他事件(索引已更改)。
if (objLstTypes.SelectedItem != null)
{
PublisherTypeDescriptor objType = (PublisherTypeDescriptor)objLstTypes.SelectedItem;
objLstTypes.Items.Remove(objType);
objLstTypes.Items.Add(objType);
objLstTypes.SelectedItem = objType;
}
回答by zeemz
I don't know much about vb.net but in C# you should use datasource and then bind it by calling listbox.bind()would do the trick.
我对 vb.net 了解不多,但在 C# 中,您应该使用数据源,然后通过调用绑定它就listbox.bind()可以了。
回答by zeemz
If objLstTypes is your ListBox name Use objLstTypes.Items.Refresh(); Hope this works...
如果 objLstTypes 是您的 ListBox 名称,请使用 objLstTypes.Items.Refresh(); 希望这有效...

