You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何自定义NumericUpDown,让ValueChanged事件传递CancelEventArgs?

实现可取消值变更的自定义NumericUpDown控件

你遇到的问题核心在于:基类NumericUpDownOnValueChanged方法签名是固定的(接收EventArgs),重写方法必须完全匹配基类的参数类型,所以你的代码才会报错。而且原ValueChanged事件是在值已经改变后触发的,就算能修改参数,也没法实现“取消编辑”的需求。不过别担心,我们可以换个思路:新增一个带CancelEventArgs的自定义事件,同时拦截所有可能修改值的操作,在值真正改变前触发这个事件,让你有机会取消编辑。

1. 自定义控件完整代码

创建一个继承自NumericUpDown的类,重写必要的方法并添加自定义事件:

using System.Windows.Forms;

public class CancelableNumericUpDown : NumericUpDown
{
    // 定义带取消功能的自定义事件
    public event CancelEventHandler CancelableValueChanged;

    // 重写Value属性,拦截直接设置值的操作
    public override decimal Value
    {
        get => base.Value;
        set
        {
            decimal originalValue = base.Value;
            // 值未变化时直接返回,避免不必要的事件触发
            if (originalValue == value) return;

            CancelEventArgs e = new CancelEventArgs();
            // 触发自定义取消事件
            OnCancelableValueChanged(e);

            if (!e.Cancel)
            {
                // 允许变更,调用基类设置值
                base.Value = value;
            }
            else
            {
                // 取消变更,恢复文本框显示原数值
                Text = originalValue.ToString(FormatString);
            }
        }
    }

    // 重写UpButton方法,拦截向上按钮操作
    public override void UpButton()
    {
        decimal newValue = base.Value + base.Increment;
        CancelEventArgs e = new CancelEventArgs();
        OnCancelableValueChanged(e);

        if (!e.Cancel)
        {
            base.UpButton();
        }
    }

    // 重写DownButton方法,拦截向下按钮操作
    public override void DownButton()
    {
        decimal newValue = base.Value - base.Increment;
        CancelEventArgs e = new CancelEventArgs();
        OnCancelableValueChanged(e);

        if (!e.Cancel)
        {
            base.DownButton();
        }
    }

    // 触发自定义事件的保护方法
    protected virtual void OnCancelableValueChanged(CancelEventArgs e)
    {
        CancelableValueChanged?.Invoke(this, e);
    }
}

2. 使用示例(实现两个控件值不同的需求)

在窗体中添加两个CancelableNumericUpDown控件(假设命名为num1num2),然后绑定自定义事件:

private void num1_CancelableValueChanged(object sender, CancelEventArgs e)
{
    var currentCtrl = sender as CancelableNumericUpDown;
    if (currentCtrl != null && currentCtrl.Value == num2.Value)
    {
        e.Cancel = true;
        MessageBox.Show("两个数值不能相同,请重新输入!");
    }
}

private void num2_CancelableValueChanged(object sender, CancelEventArgs e)
{
    var currentCtrl = sender as CancelableNumericUpDown;
    if (currentCtrl != null && currentCtrl.Value == num1.Value)
    {
        e.Cancel = true;
        MessageBox.Show("两个数值不能相同,请重新输入!");
    }
}

这样不管是直接修改控件值,还是点击上下按钮,都会先触发自定义的取消事件,你可以在事件处理逻辑中判断是否允许值变更。

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

火山引擎 最新活动