桌面健身软件:表单数据回显至pg_KurzfristigeTrainingsplanung页面失败
问题:WinForms训练计划数据回显失效+持久化实现
我正在开发一款健身桌面软件,主窗体中有「短期计划」页面pg_KurzfristigeTrainingsplanung。从该页面调用表单frm_KurzfristigeTrainingsplanung录入训练日期与内容,希望通过按钮将数据回显至原页面,且数据需持久保留(含关闭程序后)。
尝试以下代码实现数据回传,但执行后pg_KurzfristigeTrainingsplanung页面未显示预期数据:
private void btnEintragen_Click(object sender, EventArgs e) { pg_KurzfristigeTrainingsplanung pgKF = pg_KurzfristigeTrainingsplanung; // Schleife von 1 bis 7 for (int i = 1; i <= 7; i++) { if (i == 1) { // Spezialfall für i = 1: DateTimePicker und TextBox DateTimePicker dtpDatum1 = (DateTimePicker)this.Controls.Find("dtpDatum1", true).FirstOrDefault(); Label lblDatum1 = (Label)pgKF.Controls.Find("lblDatum1", true).FirstOrDefault(); if (dtpDatum1 != null) // && lblDatum1 != null { lblDatum1.Text = dtpDatum1.Value.ToString("dd.MM.yyyy"); } } else { // Standardfall für i = 2 bis 7: Labels Label lblDatumFormKF = (Label)this.Controls.Find("lblDatum" + i, true).FirstOrDefault(); Label lblTrainingFormKF = (Label)this.Controls.Find("lblTraining" + i, true).FirstOrDefault(); Label lblFocusFormKF = (Label)this.Controls.Find("lblFocus" + i, true).FirstOrDefault(); Label lblDatumpgKF = (Label)pgKF.Controls.Find("lblDatum" + i, true).FirstOrDefault(); Label lblTrainingpgKF = (Label)pgKF.Controls.Find("lblTraining" + i, true).FirstOrDefault(); Label lblFocuspgKF = (Label)pgKF.Controls.Find("lblFocus" + i, true).FirstOrDefault(); // Falls die Controls gefunden wurden, deren Text übertragen if (lblDatumFormKF != null && lblDatumpgKF != null) { lblDatumpgKF.Text = lblDatumFormKF.Text; } if (lblTrainingFormKF != null && lblTrainingpgKF != null) { lblTrainingpgKF.Text = lblTrainingFormKF.Text; } if (lblFocusFormKF != null && lblFocuspgKF != null) { lblFocuspgKF.Text = lblFocusFormKF.Text; } } } //Schliesst die Form nach erfolgreichem Eintragen der Daten this.Close(); }
解决方案
一、修复数据回显失效问题
代码核心问题是未获取到主窗体中正在显示的pg_KurzfristigeTrainingsplanung实例,直接引用类名无法指向当前页面对象;同时空引用判断不完整,可能导致赋值逻辑未执行。
1. 传递正确的页面实例
在主页面调用表单时,将当前页面实例传递给表单:
// 主页面中打开表单的代码 frm_KurzfristigeTrainingsplanung frm = new frm_KurzfristigeTrainingsplanung(); frm.TargetPage = this; // 表单新增属性接收目标页面 frm.ShowDialog();
在表单类中新增属性:
public pg_KurzfristigeTrainingsplanung TargetPage { get; set; }
2. 修正按钮点击事件中的实例引用
替换原代码中的pg_KurzfristigeTrainingsplanung pgKF = pg_KurzfristigeTrainingsplanung;为:
var pgKF = TargetPage;
3. 补全空引用判断
将第1天的判断条件补全,避免空引用导致赋值失败:
if (dtpDatum1 != null && lblDatum1 != null) { lblDatum1.Text = dtpDatum1.Value.ToString("dd.MM.yyyy"); }
二、实现数据持久化
要实现关闭程序后数据保留,需将数据序列化存储到本地(推荐JSON文件,轻量易实现)。
1. 创建训练计划实体类
public class TrainingPlanItem { public DateTime Date { get; set; } public string TrainingContent { get; set; } = string.Empty; public string Focus { get; set; } = string.Empty; } public class ShortTermTrainingPlan { public List<TrainingPlanItem> Items { get; set; } = new List<TrainingPlanItem>(); }
2. 表单中收集并保存数据
修改按钮点击事件,先收集数据到实体,再序列化到文件,最后更新主页面:
private void btnEintragen_Click(object sender, EventArgs e) { // 1. 收集表单数据到实体 var plan = new ShortTermTrainingPlan(); // 处理第1天 DateTimePicker dtpDatum1 = (DateTimePicker)this.Controls.Find("dtpDatum1", true).FirstOrDefault(); TextBox txtTraining1 = (TextBox)this.Controls.Find("txtTraining1", true).FirstOrDefault(); TextBox txtFocus1 = (TextBox)this.Controls.Find("txtFocus1", true).FirstOrDefault(); if (dtpDatum1 != null) { plan.Items.Add(new TrainingPlanItem { Date = dtpDatum1.Value, TrainingContent = txtTraining1?.Text ?? string.Empty, Focus = txtFocus1?.Text ?? string.Empty }); } // 处理第2-7天 for (int i = 2; i <= 7; i++) { Label lblDatum = (Label)this.Controls.Find("lblDatum" + i, true).FirstOrDefault(); Label lblTraining = (Label)this.Controls.Find("lblTraining" + i, true).FirstOrDefault(); Label lblFocus = (Label)this.Controls.Find("lblFocus" + i, true).FirstOrDefault(); if (lblDatum != null && DateTime.TryParse(lblDatum.Text, out DateTime date)) { plan.Items.Add(new TrainingPlanItem { Date = date, TrainingContent = lblTraining?.Text ?? string.Empty, Focus = lblFocus?.Text ?? string.Empty }); } } // 2. 序列化到JSON文件(存储在应用数据目录,避免权限问题) string appDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FitnessApp"); Directory.CreateDirectory(appDataPath); string filePath = Path.Combine(appDataPath, "ShortTermPlan.json"); string json = JsonSerializer.Serialize(plan); File.WriteAllText(filePath, json); // 3. 更新主页面显示 if (TargetPage != null) { TargetPage.LoadTrainingPlan(plan); } this.Close(); }
3. 主页面加载数据
在pg_KurzfristigeTrainingsplanung中添加加载数据的方法,页面初始化时自动加载:
public void LoadTrainingPlan(ShortTermTrainingPlan plan = null) { // 若未传入数据,从文件读取 if (plan == null) { string filePath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "FitnessApp", "ShortTermPlan.json"); if (File.Exists(filePath)) { string json = File.ReadAllText(filePath); plan = JsonSerializer.Deserialize<ShortTermTrainingPlan>(json); } else { plan = new ShortTermTrainingPlan(); } } // 更新页面控件 // 第1天 Label lblDatum1 = (Label)this.Controls.Find("lblDatum1", true).FirstOrDefault(); Label lblTraining1 = (Label)this.Controls.Find("lblTraining1", true).FirstOrDefault(); Label lblFocus1 = (Label)this.Controls.Find("lblFocus1", true).FirstOrDefault(); if (plan.Items.Count >= 1 && lblDatum1 != null) { lblDatum1.Text = plan.Items[0].Date.ToString("dd.MM.yyyy"); lblTraining1.Text = plan.Items[0].TrainingContent; lblFocus1.Text = plan.Items[0].Focus; } // 第2-7天 for (int i = 2; i <= 7; i++) { int itemIndex = i - 1; Label lblDatum = (Label)this.Controls.Find("lblDatum" + i, true).FirstOrDefault(); Label lblTraining = (Label)this.Controls.Find("lblTraining" + i, true).FirstOrDefault(); Label lblFocus = (Label)this.Controls.Find("lblFocus" + i, true).FirstOrDefault(); if (itemIndex < plan.Items.Count && lblDatum != null) { lblDatum.Text = plan.Items[itemIndex].Date.ToString("dd.MM.yyyy"); lblTraining.Text = plan.Items[itemIndex].TrainingContent; lblFocus.Text = plan.Items[itemIndex].Focus; } } } // 页面加载时自动读取数据 private void pg_KurzfristigeTrainingsplanung_Load(object sender, EventArgs e) { LoadTrainingPlan(); }
内容的提问来源于stack exchange,提问作者Dominique Müller
相关产品推荐
相关产品推荐

