已打开的Form表单如何写入数据并成功在界面刷新显示?
解决方案
以下是WinForm场景下该问题的几类常见原因及对应修复方式:
1. 跨线程操作控件导致更新失效
WinForm控件只能由创建它的UI线程修改,如果你是从开票窗口、后台业务线程直接给第二屏的Form控件赋值,就会出现代码赋值成功但界面不刷新的情况,部分场景下不会抛出显式异常。
修复方式:在第二屏的结算Form中封装线程安全的更新方法:
// 结算Form类内的公共更新方法 public void RefreshInvoiceData(string invoiceNo, decimal price, decimal subtotal, decimal vat, decimal total) { // 判断是否需要切回UI线程执行 if (this.InvokeRequired) { this.Invoke(new Action(() => RefreshInvoiceData(invoiceNo, price, subtotal, vat, total))); return; } // 控件赋值 lblInvoiceNo.Text = invoiceNo; lblPrice.Text = price.ToString("F2"); lblSubtotal.Text = subtotal.ToString("F2"); lblVat.Text = vat.ToString("F2"); lblTotal.Text = total.ToString("F2"); // 强制刷新界面 this.Refresh(); }
2. 操作了错误的Form实例
很多场景下开发者传值时会重新new一个结算Form的新实例,而不是程序启动时已经在第二屏打开的那一个实例,修改新实例的属性自然不会同步到已显示的界面上。
修复方式:全局持有启动时创建的结算Form实例,比如在Program.cs中定义静态变量存储:
// Program.cs中添加全局实例存储 public static SettlementForm RunningSettlementForm; [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // 启动时初始化第二屏的结算窗口并存入全局变量 RunningSettlementForm = new SettlementForm(); if (Screen.AllScreens.Length > 1) { Screen secondScreen = Screen.AllScreens[1]; RunningSettlementForm.StartPosition = FormStartPosition.Manual; RunningSettlementForm.Bounds = secondScreen.Bounds; RunningSettlementForm.Show(); } Application.Run(new MainPosForm()); }
开票时直接调用全局实例的更新方法即可:
Program.RunningSettlementForm.RefreshInvoiceData("36", 128, 128, 15.36, 143.36);
3. 数据绑定未触发变更通知
如果你用了数据源绑定控件内容,需要确保数据源类实现了INotifyPropertyChanged接口,属性变更时主动触发PropertyChanged事件,否则绑定的控件不会自动刷新。
内容的提问来源于stack exchange,提问作者julio hernandez
相关产品推荐
相关产品推荐

