我创建了一个ListBoxItem
,其中我有一个属性Name
并覆盖ToString()
以返回名称。当我添加新项目时,这很好用。
但是现在我需要在更改船名时强制ListBox
更新标签。我认为刷新或更新会这样做,但那不起作用。
我可能会在这里遗漏一些东西。
public class ShipListBoxItem
{
public ListBox Parent { get; set; }
public ShipType Ship { get; set; }
public ShipListBoxItem()
{
Ship = new ShipType();
}
public ShipListBoxItem(ShipType st)
{
Ship = st;
}
public override string ToString()
{
return Ship.Name;
}
public void UpdateListBox()
{
Parent.Refresh(); //My problem is here. Update doesn't work either.
}
public static ShipListBoxItem AddToListBox(ListBox lb, ShipType ship)
{
ShipListBoxItem li = new ShipListBoxItem(ship);
li.Parent = lb;
lb.Items.Add(li);
return li;
}
}
答案 0 :(得分:1)
试试这个
ListBox.RefreshItems()
编辑:您可以使用这样的扩展类:
public class FooLisBox : System.Windows.Forms.ListBox
{
public void RefreshAllItems()
{
RefreshItems();
}
}
private void button1_Click(object sender, EventArgs e)
{
(listBox1.Items[0] as ShipListBoxItem).Ship.Name = "AAAA";
listBox1.RefreshAllItems();
}
答案 1 :(得分:1)
如果您使用List<T>
作为列表框的DataSource
,则很容易对项目进行更改。这也意味着没有真正的理由让我有一个特殊的类来向ListBox添加ShipListBoxItem
,你的基本Ship
类可以工作:
class ShipItem
{
public enum ShipTypes { BattleShip, Carrier, Destroyer, Submarine, Frigate };
public ShipTypes Ship { get; set; }
public string Name { get; set; }
public ShipItem(string n, ShipTypes st)
{
Name = n;
Ship = st;
}
public override string ToString()
{
return String.Format("{0}: {1}", Ship.ToString(), Name);
}
}
与表单相关的内容:
private void Form1_Load(object sender, EventArgs e)
{
// add some ships
Ships = new List<ShipItem>();
Ships.Add(new ShipItem("USS Missouri", ShipTypes.BattleShip));
Ships.Add(new ShipItem("USS Ronald Reagan", ShipTypes.Carrier));
lb.DataSource = Ships;
}
private void button1_Click(object sender, EventArgs e)
{
// change a ship name
lb.DataSource = null; // suspend binding
this.Ships[0].Name = "USS Iowa";
lb.DataSource = Ships; // rebind
lb.Refresh();
}
作为替代方案,您还可以使用DisplayMember
告诉列表框使用特定属性进行显示:
lb.DataSource = Ships;
lb.DisplayMember = "Name";
这将使用列表框中的Name属性而不是ToString
方法。如果您的列表发生了很大变化,请改用BindingList
。当你添加它们而不切换DataSource时,它将允许更改列表框中显示的列表。
答案 2 :(得分:0)
我设法解决了我的问题。
大多数情况下,感谢Jose M.
然而,我遇到了一个问题。 RefreshItems()触发OnSelectedIndexChanged()所以我的被覆盖的类看起来像这样
public class MyListBox : ListBox
{
public bool DoEvents{ get; set; } // Made it public so in the future I can block event triggering externally
public MyListBox()
{
DoEvents = true;
}
public void RefreshAllItems()
{
SuspendLayout();
DoEvents = false;
base.RefreshItems(); // this triggers OnSelectedIndexChanged as it selects the selected item again
DoEvents = true;
ResumeLayout();
}
// I only use this event but you can add all events you need to block
protected override void OnSelectedIndexChanged(EventArgs e)
{
if (DoEvents)
base.OnSelectedIndexChanged(e);
}
}