跨窗体下通过IF条件将GridView单元格内容显示到TextBox失效问题求助
问题排查与解决方案:访客停留时间对应费率显示失效
问题背景
数据源
GridView(TicketRateView)的数据源是以下CSV内容:
Child(5-12),400,800,1050,1450,2200 Adult(>12),550,1000,1500,2100,2700 Group of 5,3000,5000,8000,12500,25000 Group of 10,5000,8000,15000,22000,40000
数据存储逻辑
已经将GridView的单元格内容存储到全局列表GlobalValues.UpdatedrateList中,代码如下:
GlobalValues.UpdatedrateList = new List<Ticketpricerate>(); for (int i=0; i<TicketRateView.Rows.Count; i++) { Ticketpricerate rate = new Ticketpricerate(); rate.Ticket_Category = TicketRateView.Rows[i].Cells[0].Value.ToString(); rate.Rate_for_1hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[1].Value); rate.Rate_for_2hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[2].Value); rate.Rate_for_3hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[3].Value); rate.Rate_for_4hr = Convert.ToInt32(TicketRateView.Rows[i].Cells[4].Value); rate.Rate_for_wholeday = Convert.ToInt32(TicketRateView.Rows[i].Cells[5].Value); GlobalValues.UpdatedrateList.Add(rate); }
需求与问题
在另一个窗体中,通过visitorstaytime TextBox获取访客停留时间(分钟),希望根据该时间将对应费率显示到pay_amount TextBox中(例如停留60分钟时显示1小时费率)。但编写的点击事件代码未生效,代码如下:
private void Pay_amount_Click(object sender, System.EventArgs e) { int timeofstay = Convert.ToInt32(visitorstaytime.Text); foreach (Ticketpricerate rate in GlobalValues.UpdatedrateList) { if (timeofstay == 60) { pay_amount.Text = rate.Rate_for_1hr.ToString(); } } }
失效原因分析
咱们一步步拆解问题,就能找到代码不生效的核心原因:
- 遍历覆盖问题:你的
foreach循环会遍历所有票种费率,每次匹配到60分钟时,都会把pay_amount的内容覆盖成当前票种的1小时费率。最后显示的只会是列表最后一个票种(也就是Group of 10)的费率,而用户实际需要的是自己选择的对应票种费率——你完全没处理票种选择的逻辑! - 事件触发时机错误:你把计算逻辑写在了
Pay_amount_Click事件里,也就是点击结果文本框时才触发。正常流程应该是用户输入时间、选好票种后,点击一个计算按钮,或者输入变化时自动计算,而不是点结果框才执行。 - 未处理非法输入:如果
visitorstaytime里输入的不是数字,Convert.ToInt32会直接抛出异常,导致代码完全执行失败。 - 时间判断太死板:目前只处理了刚好60分钟的情况,实际场景中用户停留61分钟(该按2小时算吧?)或者30分钟(按1小时算?)的情况完全没覆盖,逻辑不完整。
解决方案
我们把这些问题逐一修复,下面是完整的改进方案:
第一步:添加票种选择控件
首先在窗体上放一个ComboBox(命名为ticketCategoryCombo),用来让用户选择票种。然后在窗体加载时,把全局列表里的票种填充进去:
private void YourForm_Load(object sender, EventArgs e) { // 填充票种下拉选项 foreach (var rate in GlobalValues.UpdatedrateList) { ticketCategoryCombo.Items.Add(rate.Ticket_Category); } // 默认选中第一个票种 if (ticketCategoryCombo.Items.Count > 0) { ticketCategoryCombo.SelectedIndex = 0; } }
第二步:修复计算逻辑(用按钮触发)
把计算逻辑移到一个专门的按钮(比如btnCalculate)的点击事件里,同时处理异常输入、票种匹配和灵活的时间判断:
private void btnCalculate_Click(object sender, EventArgs e) { // 1. 校验停留时间输入是否有效 if (!int.TryParse(visitorstaytime.Text, out int timeofstay)) { MessageBox.Show("请输入有效的停留时间(数字)!"); pay_amount.Text = string.Empty; return; } // 2. 校验是否选择了票种 if (ticketCategoryCombo.SelectedItem == null) { MessageBox.Show("请先选择票种类别!"); pay_amount.Text = string.Empty; return; } string selectedCategory = ticketCategoryCombo.SelectedItem.ToString(); // 3. 找到用户选择的票种对应的费率对象 var selectedRate = GlobalValues.UpdatedrateList.FirstOrDefault(r => r.Ticket_Category == selectedCategory); if (selectedRate == null) { MessageBox.Show("未找到对应的费率信息!"); pay_amount.Text = string.Empty; return; } // 4. 根据停留时间匹配对应费率(这里用"向上取整"逻辑,可根据需求调整) int rateAmount = 0; if (timeofstay <= 60) { rateAmount = selectedRate.Rate_for_1hr; } else if (timeofstay <= 120) { rateAmount = selectedRate.Rate_for_2hr; } else if (timeofstay <= 180) { rateAmount = selectedRate.Rate_for_3hr; } else if (timeofstay <= 240) { rateAmount = selectedRate.Rate_for_4hr; } else { rateAmount = selectedRate.Rate_for_wholeday; } // 5. 显示计算结果 pay_amount.Text = rateAmount.ToString(); }
第三步:可选优化——自动计算
如果希望用户输入时间或切换票种时自动计算,可以给visitorstaytime添加TextChanged事件,给ticketCategoryCombo添加SelectedIndexChanged事件,直接调用计算逻辑:
private void visitorstaytime_TextChanged(object sender, EventArgs e) { btnCalculate_Click(sender, e); } private void ticketCategoryCombo_SelectedIndexChanged(object sender, EventArgs e) { btnCalculate_Click(sender, e); }
内容的提问来源于stack exchange,提问作者Netra Rana
相关产品推荐
相关产品推荐

