Files
IOT_SIM/runtime/Sim.WinForms/Forms/ListControl.cs
T
xuyueandClaude Opus 5.5 91b39603a2 项目 5 补齐:旧版线程 API(Suspend / Resume / Abort)与 ListBox
- 编译时把 Thread 的 Suspend / Resume / Abort、ThreadState、Sleep、new Thread 改写成平台的
  协作式实现:被挂起或终止的线程在 Sleep、后台改控件、调设备类库、弹提示框时停下或结束;
  ThreadStateException 等行为与 .NET Framework 一致;编辑器不再提示"已过时"
- ListBox:列表项、单选、SelectedIndexChanged 先于 Click、删除选中项后取消选中;
  ComboBox 与 ListBox 共用 ListControl 和列表项集合;设计器工具箱加"列表框"
- 评分规则的"包含"对列表框检查所有列表项
- 示例:项目 5 任务 2(烟雾,线程)、任务 3(推送灾情,二维数组、两个窗体、ListBox),
  参考答案修正书上直接 Abort 挂起线程、烟雾记成"发现火情"的问题
- 一直不换行的 Console 输出攒满 4096 字符先发出,避免占满内存
- 测试:旧版线程 API、ListBox 事件顺序、两个示例的端到端和评分测试

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-22 20:33:12 +08:00

115 lines
3.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace System.Windows.Forms;
/// <summary>ComboBox 和 ListBox 的共同基类:列表项、选中项</summary>
public abstract class ListControl : Control
{
/// <summary>选中项的序号。列表项增删时直接调整(和 WinForms 一样不触发 SelectedIndexChanged)</summary>
private protected int SelectedIndexValue = -1;
public abstract int SelectedIndex { get; set; }
public string DisplayMember { get; set; } = "";
public string ValueMember { get; set; } = "";
public event EventHandler? SelectedValueChanged;
protected virtual void OnSelectedValueChanged(EventArgs e) => SelectedValueChanged?.Invoke(this, e);
public string GetItemText(object? item) => item?.ToString() ?? "";
/// <summary>列表项变化后调用:把新的列表和选中项发给浏览器</summary>
internal abstract void ItemsChanged();
/// <summary>Items.Clear() 时调用:先取消选中,再刷新列表</summary>
internal abstract void ItemsCleared();
internal void ItemInserted(int index)
{
if (SelectedIndexValue >= index) SelectedIndexValue++;
ItemsChanged();
}
/// <summary>删掉的正是选中项时取消选中,删掉前面的项时选中项序号前移</summary>
internal void ItemRemoved(int index)
{
if (SelectedIndexValue == index) SelectedIndexValue = -1;
else if (SelectedIndexValue > index) SelectedIndexValue--;
ItemsChanged();
}
protected string[] ItemTexts(IEnumerable<object?> items) => items.Select(GetItemText).ToArray();
}
/// <summary>ComboBox.ObjectCollection 和 ListBox.ObjectCollection 共用的实现</summary>
public abstract class ListItemCollection : IList, IEnumerable<object?>
{
private readonly List<object?> _items = new();
private readonly ListControl _owner;
private protected ListItemCollection(ListControl owner) => _owner = owner;
public int Count => _items.Count;
public bool IsReadOnly => false;
bool IList.IsFixedSize => false;
bool ICollection.IsSynchronized => false;
object ICollection.SyncRoot => this;
public object? this[int index]
{
get => _items[index];
set
{
_items[index] = value;
_owner.ItemsChanged();
}
}
public int Add(object? item)
{
if (item == null) throw new ArgumentNullException(nameof(item), "值不能为 null。");
_items.Add(item);
_owner.ItemsChanged();
return _items.Count - 1;
}
public void AddRange(object[] items)
{
_items.AddRange(items);
_owner.ItemsChanged();
}
public void Insert(int index, object? item)
{
_items.Insert(index, item);
_owner.ItemInserted(index);
}
public void Remove(object? item)
{
var index = _items.IndexOf(item);
if (index >= 0) RemoveAt(index);
}
public void RemoveAt(int index)
{
_items.RemoveAt(index);
_owner.ItemRemoved(index);
}
public void Clear()
{
_items.Clear();
_owner.ItemsCleared();
}
public bool Contains(object? item) => _items.Contains(item);
public int IndexOf(object? item) => _items.IndexOf(item);
public void CopyTo(Array array, int index) => ((ICollection)_items).CopyTo(array, index);
public IEnumerator<object?> GetEnumerator() => _items.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}