You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#双ListView关联添加详情时触发索引越界问题求助

修复WinForms双ListView关联详情的索引越界问题

核心问题分析

触发“index is out of range”错误的主要原因:

  • 团队详情列表_lColStaffs未与团队列表_lRowStaffs同步,添加团队时未对应初始化详情列表,导致选中团队时索引无效
  • 添加详情时错误地向_lColStaffs添加新列表,而非追加到当前选中团队的详情列表中
  • ListView更新逻辑错误,循环遍历了错误的集合长度
  • 团队数据添加时未将创建的Staff对象存入列表,导致数据丢失
  • 选中项判断逻辑存在边界错误,未处理无选中项的情况

分步修复方案

  1. 同步团队与详情列表
    添加团队时,不仅要向_lRowStaffs添加Staff对象,还要向_lColStaffs添加一个空的List<Staff0>,确保两者数量一致:

    // btn_Add_Click修正
    _lRowStaffs.Add(newStaff);
    _lColStaffs.Add(new List<Staff0>());
    
  2. 修正详情添加逻辑
    添加详情时,先校验选中团队索引的有效性,再将新创建的Staff0对象追加到对应索引的详情列表中:

    // btnadd_Click修正
    int selectedTeamIndex = GetStaffCount.SelItem;
    if (selectedTeamIndex >= 0 && selectedTeamIndex < _lColStaffs.Count)
    {
        _lColStaffs[selectedTeamIndex].Add(newStaffDetail);
        UpdateListView(lv_Staffs);
    }
    else
    {
        MessageBox.Show("请先选中一个团队");
    }
    
  3. 修复ListView更新逻辑

    • 更新团队列表时,遍历_lRowStaffs集合,使用当前索引的Staff对象填充项,而非全局变量
    • 更新详情列表时,遍历当前选中团队对应的详情列表,同时先判断索引有效性:
    // UpdateListView中lv_Staffs部分修正
    int selectedTeamIndex = GetStaffCount.SelItem;
    if (selectedTeamIndex >= 0 && selectedTeamIndex < _lColStaffs.Count)
    {
        lv.Columns.Add("Segment", 150);
        lv.Columns.Add("Variable", 100);
        lv.Columns.Add("Partly", 200);
        foreach (var staffDetail in _lColStaffs[selectedTeamIndex])
        {
            lvi = new ListViewItem(staffDetail.Seg);
            lvi.SubItems.Add(staffDetail.Var);
            lvi.SubItems.Add(staffDetail.Par);
            lv.Items.Add(lvi);
        }
    }
    
  4. 修正团队选中事件逻辑
    先判断是否有选中项,再更新选中索引并同步刷新详情列表:

    // lv_Team_MouseClick修正
    if (lv_Team.SelectedItems.Count == 0) return;
    GetStaffCount.SelItem = lv_Team.Items.IndexOf(lv_Team.SelectedItems[0]);
    UpdateListView(lv_Staffs);
    
  5. 补全Staff类缺失属性
    代码中使用了Department属性但未定义,需补充:

    public class Staff
    {
        private string department = "";
        public string Department { get { return department; } set { department = value; } }
        // 其他原有属性...
    }
    
  6. 添加输入校验
    对年龄输入增加数字校验,避免非数字输入导致崩溃:

    if (int.TryParse(txt_Age.Text, out int age))
    {
        newStaff.Age = age;
    }
    else
    {
        MessageBox.Show("年龄请输入有效数字");
        return;
    }
    

完整修正后的代码

public partial class Form1 : Form
{
    public class Staff
    {
        private string team = "";
        private int age = 0;
        private string department = "";
        private int count = 2;
        public string Team { get { return team; } set { team = value; } }
        public int Age { get { return age; } set { age = value; } }
        public string Department { get { return department; } set { department = value; } }
        public int Count { get { return count; } }
        public Staff()
        {
        }
    }

    public class Staff0
    {
        private string seg = "";
        private string var = "";
        private string par = "";
        public string Seg { get { return seg; } set { seg = value; } }
        public string Par { get { return par; } set { par = value; } }
        public string Var { get { return var; } set { var = value; } }
        public Staff0(string sseg, string svar, string spar)
        {
            seg = sseg;
            var = svar;
            par = spar;
        }
    }

    public class StaffCount
    {
        private int count = 0;
        private int selitem = -1; // 初始化为-1,表示未选中
        public int Count { get { return count; } set { count = value; } }
        public int SelItem { get { return selitem; } set { selitem = value; } }
    }

    List<Staff> _lRowStaffs = new List<Staff>();
    List<List<Staff0>> _lColStaffs = new List<List<Staff0>>();
    StaffCount GetStaffCount = new StaffCount();

    public Form1()
    {
        InitializeComponent();
        UpdateListView(lv_Team);
    }

    private void btn_Add_Click(object sender, EventArgs e)
    {
        Staff newStaff = new Staff();
        newStaff.Team = txt_Name.Text;
        
        // 年龄输入校验
        if (int.TryParse(txt_Age.Text, out int age))
        {
            newStaff.Age = age;
        }
        else
        {
            MessageBox.Show("年龄请输入有效数字");
            return;
        }
        
        newStaff.Department = txt_Dept.Text;

        _lRowStaffs.Add(newStaff);
        _lColStaffs.Add(new List<Staff0>()); // 同步初始化详情列表
        UpdateListView(lv_Team);
    }

    private void UpdateListView(ListView lv)
    {
        lv.Clear();
        ListViewItem lvi;
        try
        {
            if (lv == lv_Team)
            {
                lv.Columns.Add("Team", 400);
                lv.Columns.Add("Number Staffs", 120);

                for (int i = 0; i < _lRowStaffs.Count; i++)
                {
                    lvi = new ListViewItem(_lRowStaffs[i].Team);
                    lvi.SubItems.Add(Convert.ToString(_lRowStaffs[i].Age));
                    lv.Items.Add(lvi);
                }
            }
            else if (lv == lv_Staffs)
            {
                int selectedTeamIndex = GetStaffCount.SelItem;
                if (selectedTeamIndex >= 0 && selectedTeamIndex < _lColStaffs.Count)
                {
                    lv.Columns.Add("Segment", 150);
                    lv.Columns.Add("Variable", 100);
                    lv.Columns.Add("Partly", 200);

                    foreach (var staffDetail in _lColStaffs[selectedTeamIndex])
                    {
                        lvi = new ListViewItem(staffDetail.Seg);
                        lvi.SubItems.Add(staffDetail.Var);
                        lvi.SubItems.Add(staffDetail.Par);
                        lv.Items.Add(lvi);
                    }
                }
            }
        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }
    }

    private void lv_Team_MouseClick(object sender, MouseEventArgs e)
    {
        if (lv_Team.SelectedItems.Count == 0) return;
        GetStaffCount.SelItem = lv_Team.Items.IndexOf(lv_Team.SelectedItems[0]);
        UpdateListView(lv_Staffs); // 选中团队后立即刷新详情
    }

    private void btnadd_Click(object sender, EventArgs e)
    {
        int selectedTeamIndex = GetStaffCount.SelItem;
        if (selectedTeamIndex < 0 || selectedTeamIndex >= _lColStaffs.Count)
        {
            MessageBox.Show("请先选中一个团队");
            return;
        }

        Staff0 newStaffDetail = new Staff0(txtseg.Text, txtvar.Text, txtpar.Text);
        _lColStaffs[selectedTeamIndex].Add(newStaffDetail);
        UpdateListView(lv_Staffs);
    }
}

内容的提问来源于stack exchange,提问作者Ahmed Jab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 22:57:27