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

C#删除已保存文件后无法保存新文件:空引用异常问题

问题:删除后新建TextBox保存时触发空引用异常

功能说明

  • 动态生成TextBox
  • 提取TextBox文本并保存为TXT文件
  • 删除文本文件

相关代码

生成TextBox按钮代码

// Generate notes
int curr = 0;
private void guna2Button1_Click(object sender, EventArgs e) {
    int top = 25;
    int h_p = 170;
    curr++;
    var new_note = new Guna2TextBox() {
        Text = "Title\n",
        Name = "Note" + curr,
        Multiline = true,
        AcceptsTab = true,
        AcceptsReturn = true,
        WordWrap = false,
        ScrollBars = ScrollBars.Vertical,
        Width = 220,
        Height = 110,
        BorderRadius = 8,
        Font = new Font("Bahnschrift", 13),
        ForeColor = Color.White,
        FillColor = ColorTranslator.FromHtml("#1E1E1E"),
        BorderColor = ColorTranslator.FromHtml("#2C2C2C"),
        Location = new Point(450,top)
    };
    top += h_p;
    flowLayoutPanel1.Controls.Add(new_note);
}

保存TextBox文本到文件按钮代码

// Save notes
private void guna2Button7_Click(object sender, EventArgs e) {
    for(int j=1; j<flowLayoutPanel1.Controls.Count+1; j++) {
        var notes = ((Guna2TextBox)flowLayoutPanel1.Controls["Note" + j]);         
        var messages = notes.Text;
        var titles = notes.Lines[0];
        string notes_path = @"C:\NOTES_LOC\DATA_LOC\" + titles + ".txt";
        try {
            if(titles != "") { 
                using(FileStream fs = File.Create(notes_path)) {
                    Byte[] notes_texts = new UTF8Encoding(true).GetBytes(messages);
                    fs.Write(notes_texts,0,notes_texts.Length);
                 }
           } else {
               MessageBox.Show("Title cannot be empty", "Flow Notes System");
            }
        } catch (Exception eq) {
            MessageBox.Show(eq.ToString(),"Notes System");
        }
    }
}

删除文本文件按钮代码

// Delete notes
private void guna2Button5_Click(object sender, EventArgs e) {
    DirectoryInfo dirs_notes_source = new DirectoryInfo(@"C:\NOTES_LOC\DATA_LOC\");
    string dirs_notes = @"C:\NOTES_LOC\DATA_LOC\";
    string garb_path = @"C:\NOTES_LOC\GARBAGE_LOC\";
    if(flowLayoutPanel1.Controls.Count != 0) {
        flowLayoutPanel1.Controls.Clear();

        foreach(string dir_path in Directory.GetDirectories(dirs_notes,"*",SearchOption.AllDirectories)) {
            Directory.CreateDirectory(dir_path.Replace(dirs_notes,garb_path));
        }

        foreach(string retv_notes in Directory.GetFiles(dirs_notes,"*.*",SearchOption.AllDirectories)) {
            File.Copy(retv_notes,retv_notes.Replace(dirs_notes,garb_path),true);
        }

        foreach (FileInfo notes in dirs_notes_source.GetFiles()) {
            notes.Delete();
        }
    }
    else {
        MessageBox.Show("No note found","Flow Notes System");
    }
}

问题描述

生成TextBox后点击保存可正常保存为TXT文件,点击删除也可正常删除文件,但删除旧文件后,生成新的TextBox并尝试保存时,弹出错误:Object reference not set to an instance of an object。

调试时发现:执行var messages = notes.Text;时触发空引用异常,提示notes为null。

异常信息

************** Exception Text **************
System.NullReferenceException: Object reference not set to an instance of an object.
   at FlowNotes.Form1.guna2Button7_Click(Object sender, EventArgs e) in C:\Users\USER\source\repos\FlowNotes\FlowNotes\Form1.cs:line 136
   at System.Windows.Forms.Control.OnClick(EventArgs e)
   at Guna.UI2.WinForms.Guna2Button.OnClick(EventArgs e)
   at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

问题原因

  1. 计数器未重置:删除按钮仅清空了flowLayoutPanel1中的控件,但全局变量curr的数值没有重置。比如第一次生成3个TextBox后curr=3,删除控件后再生成新的TextBox,名字会是Note4、Note5...
  2. 保存逻辑依赖序号查找:保存代码用for循环从Note1开始按序号查找控件,但删除后新生成的控件序号已不是从1开始,导致flowLayoutPanel1.Controls["Note" + j]找不到对应控件,返回null,访问notes.Text时触发空引用异常。

修复方案

方案1:重置计数器+优化保存逻辑

步骤1:修改删除按钮代码,重置curr

在flowLayoutPanel1.Controls.Clear();后添加curr = 0;,确保新生成的TextBox从Note1开始命名:

// Delete notes
private void guna2Button5_Click(object sender, EventArgs e) {
    DirectoryInfo dirs_notes_source = new DirectoryInfo(@"C:\NOTES_LOC\DATA_LOC\");
    string dirs_notes = @"C:\NOTES_LOC\DATA_LOC\";
    string garb_path = @"C:\NOTES_LOC\GARBAGE_LOC\";
    if(flowLayoutPanel1.Controls.Count != 0) {
        flowLayoutPanel1.Controls.Clear();
        curr = 0; // 重置计数器

        foreach(string dir_path in Directory.GetDirectories(dirs_notes,"*",SearchOption.AllDirectories)) {
            Directory.CreateDirectory(dir_path.Replace(dirs_notes,garb_path));
        }

        foreach(string retv_notes in Directory.GetFiles(dirs_notes,"*.*",SearchOption.AllDirectories)) {
            File.Copy(retv_notes,retv_notes.Replace(dirs_notes,garb_path),true);
        }

        foreach (FileInfo notes in dirs_notes_source.GetFiles()) {
            notes.Delete();
        }
    }
    else {
        MessageBox.Show("No note found","Flow Notes System");
    }
}

步骤2:优化保存代码,直接遍历控件

避免依赖控件名字的序号,直接遍历flowLayoutPanel1中的Guna2TextBox控件,逻辑更健壮:

// Save notes
private void guna2Button7_Click(object sender, EventArgs e) {
    foreach (var control in flowLayoutPanel1.Controls) {
        if (control is Guna2TextBox notes) {
            var messages = notes.Text;
            var titles = notes.Lines.Length > 0 ? notes.Lines[0] : "";
            string notes_path = @"C:\NOTES_LOC\DATA_LOC\" + titles + ".txt";
            try {
                if(!string.IsNullOrEmpty(titles)) { 
                    using(FileStream fs = File.Create(notes_path)) {
                        Byte[] notes_texts = new UTF8Encoding(true).GetBytes(messages);
                        fs.Write(notes_texts,0,notes_texts.Length);
                     }
               } else {
                   MessageBox.Show("Title cannot be empty", "Flow Notes System");
                }
            } catch (Exception eq) {
                MessageBox.Show(eq.ToString(),"Notes System");
            }
        }
    }
}

方案2:完全脱离计数器(更推荐)

如果不需要通过序号标识控件,生成时可以省略Name属性,直接用类型遍历的方式保存,彻底避免序号不匹配的问题。

额外优化建议

  • 保存时添加标题非法字符检查(比如\ / : * ? " < > |),避免因标题包含非法字符导致文件创建失败。
  • 可以给每个TextBox添加唯一标识,但类型遍历的方式已经足够可靠,无需依赖名字查找。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 16:48:26