C#中ListView项转ShowItem失败及Takenshows窗体无法关闭问题
ListView项转换异常及窗体关闭失效问题修复方案
问题1:ListView项无法转换为ShowItem的类型转换异常
问题原因
listView1.Items中的元素是ListViewItem对象,并非自定义的ShowItem类型,直接使用Cast<ShowItem>()必然抛出类型转换异常。
修复方案
创建ListViewItem时,将对应的ShowItem存入其Tag属性,后续从Tag中提取即可:
- 修改
Takenshows.cs的AddItems方法:
internal void AddItems(IEnumerable<ShowItem> items) { var lvis = items.Select(x => { var lvi = new ListViewItem(new[] { x.OrderNumber.ToString(), x.MedDate.ToString(), x.Values, x.Number.ToString() }); lvi.Tag = x; // 将ShowItem关联到ListViewItem的Tag属性 return lvi; }); listView1.Items.AddRange(lvis.ToArray()); }
- 修改
Takenshows.cs的receiveItems方法,从Tag提取ShowItem:
public List<ShowItem> receiveItems() { return listView1.Items.Cast<ListViewItem>() .Select(lvi => lvi.Tag as ShowItem) .Where(item => item != null) // 过滤无效项 .ToList(); }
问题2:点击保存按钮后Takenshows窗体未关闭
问题原因
Main.cs的button1_Click方法中,你新建了一个Takenshows实例,但实际显示的窗体是之前在button2_Click中创建的,调用新实例的Close()不会影响已打开的窗体。
修复方案
获取当前已打开的Takenshows窗体实例,而非新建:
修改Main.cs的button1_Click方法:
private void button1_Click(object sender, EventArgs e) { // 获取已打开的Takenshows窗体 var shows = Application.OpenForms.OfType<Takenshows>().FirstOrDefault(); if (shows == null) { // 处理窗体未打开的情况,比如直接返回 return; } getItems = shows.receiveItems(); foreach(var x in getItems) { SaveItemsLN.getInstance().SaveItems(x.OrderNumber, x.MedDate, x.Values, x.Number); } FinishPracticeLN.getInstance().PracticeToFinish(); // 关闭已打开的窗体 shows.Close(); Close(); }
额外优化建议
由于Main.cs中已维护showItems列表(所有添加的项都存在这里),可直接使用该列表保存数据,无需从窗体提取,更高效:
private void button1_Click(object sender, EventArgs e) { foreach(var x in showItems) { SaveItemsLN.getInstance().SaveItems(x.OrderNumber, x.MedDate, x.Values, x.Number); } FinishPracticeLN.getInstance().PracticeToFinish(); var shows = Application.OpenForms.OfType<Takenshows>().FirstOrDefault(); shows?.Close(); Close(); }
内容的提问来源于stack exchange,提问作者Francisco J A
相关产品推荐
相关产品推荐

