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

绑定表单计算字段处理及BindingSource首次赋值不触发PositionChanged问题

问题1解答

直接调用事件处理方法不会干扰.NET内部运行机制,也不会引发内存泄漏、栈异常这类问题:

  • 事件处理方法本质上就是普通的实例方法,手动调用和.NET运行时触发调用的执行逻辑完全一致,唯一区别仅在于sender参数的传入值
  • 你的代码逻辑中并没有使用sender参数,传入null完全不会影响执行结果,也不会产生额外的资源引用或者调用栈溢出风险

问题2解答

有几个更合理的实现方案,既可以覆盖初始化场景,也能避免不必要的频繁触发:

  1. 先抽离公共刷新逻辑
    把展示更新的逻辑从事件处理方法中抽成独立方法,避免和事件逻辑耦合,后续不管是事件触发还是手动调用都用这个方法:
private void RefreshApprovalDisplay()
{
    var drv = talsBindingSource.Current as DataRowView;
    if (drv != null)
    {
        ctlBoundCheckButton1.lblText = $"Submitted {drv.Row.Field<DateTime>("SubmitDate").ToString("MM/dd/yy hh:mm tt")}";
        ctlBoundCheckButton1.setControls(true);
        // 未审批时清空按钮状态,避免残留上一条记录的内容
        ctlBoundCheckButton2.setControls(false);
        if (drv.Row.Field<bool>("Approved"))
        {
            var sup = talsSupervisorsBindingSource.Current as DataRowView;
            ctlBoundCheckButton2.lblText = $"Approved by {sup.Row.Field<string>("FullName")} on {drv.Row.Field<DateTime>("ApproveDate").ToString("MM/dd/yy")}";
            ctlBoundCheckButton2.setControls(true);
        }
    }
    else
    {
        using (DialogCenteringService centeringService = new DialogCenteringService(this))
        {
            MessageBox.Show("No TALs to Approve", "Confirm", MessageBoxButtons.OK);
        }
        Close();
    }
}

原来的事件处理方法直接调用这个公共方法即可:

private void ctlNavBar1_displayCurrent(object sender, EventArgs e)
{
    RefreshApprovalDisplay();
}
  1. 精准监听字段变更,避免无效触发
    不要用CurrentItemChanged这类泛用事件,直接监听DataTable的ColumnChanged事件,只有当你关心的审批相关字段实际发生变更时才触发刷新:
public TALsApprove()
{
    InitializeComponent();
    talsTableAdapter.FillForApproval(timeTrackDataSet.TALs, User.ID);
    usersTableAdapter.FillBySupervisor(timeTrackDataSet.Users, User.ID);
    timeSlipsTableAdapter.FillBySupervisor(timeTrackDataSet.TimeSlips, User.ID);
    // 注册字段变更监听,仅处理审批相关字段的变更
    timeTrackDataSet.TALs.ColumnChanged += (s, e) =>
    {
        if (e.Column.ColumnName is nameof(timeTrackDataSet.TALs.SubmitDate) 
            or nameof(timeTrackDataSet.TALs.Approved) 
            or nameof(timeTrackDataSet.TALs.ApproveDate))
        {
            RefreshApprovalDisplay();
        }
    };
    ctlNavBar1.displayCurrent += ctlNavBar1_displayCurrent;
    ctlNavBar1.bindingSource = talsBindingSource;
    // 构造函数末尾直接调用一次刷新,不需要等Shown事件(除非你的UI有布局依赖显示后的尺寸)
    RefreshApprovalDisplay();
}

这个方案可以完全避免不必要的刷新触发,只有当记录切换、或者审批相关字段实际修改时才会更新UI。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 11:39:03