我正在为一个尚未意识到控件的人做一个例子,ListBox
不需要包含字符串; 他一直在存储格式化的字符串并跳过复杂的解析箍,以便将数据从中恢复出来,ListBox
我想告诉他有更好的方法.
我注意到如果我有一个对象存储在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
我想也许问题是使用字段并尝试实现INotifyPropertyChanged,但这没有任何效果.(我使用字段的原因是因为它是一个例子,我不想添加几十行与我正在演示的主题无关.)
老实说,我以前从未尝试过更新这样的物品; 在过去,我一直在添加/删除项目,而不是编辑它们.所以我从来没有注意到我不知道如何使这项工作.
那我错过了什么?
当我需要一个更新的列表框时,我使用这个类.
更新列表中的对象,然后调用其中一个包含的方法,具体取决于您是否有可用的索引.如果要更新列表中包含的对象,但没有索引,则必须调用RefreshItems并更新所有项目.
public class RefreshingListBox : ListBox { public new void RefreshItem(int index) { base.RefreshItem(index); } public new void RefreshItems() { base.RefreshItems(); } }
lstBox.Items[lstBox.SelectedIndex] = lstBox.SelectedItem;
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_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 (); 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); } } } }
typeof(ListBox).InvokeMember("RefreshItems", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.InvokeMethod, null, myListBox, new object[] { });
在数据源和列表框的datasource属性之间使用datasource属性和BindingSource对象.然后刷新.
更新添加的示例.
像这样:
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