NumericUpDown 只允许范围内的两个幂的值

NumericUpDown that only allows a range of values of the power of two

我有一个 NumericUpDown,其最小值设置为 1,最大值为 64。我必须使用 2 的幂值将它从 1 递增到 64,因此它必须是 1, 2, 4, 8, 16, 32, 64.

我尝试了多种方法来更改 NUD 增量,但没有令人满意的结果。
我该如何解决这个问题?

如果缩小 NumericUpDown 控件的文本部分使其不可见,您可以在其旁边放置一个只读的 TextBox,使其看起来像是其中的一部分,然后...

Private Sub NumericUpDown1_ValueChanged(sender As Object, e As EventArgs) Handles NumericUpDown1.ValueChanged
    Dim nud = DirectCast(sender, NumericUpDown)
    tbForNud1.Text = (2 ^ nud.Value).ToString()
End Sub

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    tbForNud1.ReadOnly = True
    tbForNud1.Text = "1"
End Sub

您可能想要更改文本框边框的颜色:Change the borderColor of the TextBox

我建议使用派生自 NumericUpDown 的自定义控件,这样您就可以在内部处理由不同的可能操作生成的值更改事件:单击 Up/Down 按钮,旋转鼠标滚轮,手动输入数字、数据绑定等

OnValueChanged 方法覆盖有最后一句话:如果提交的值不符合条件(指定范围内的 2 的幂),则将数字更改为最接近(更高)的数字有效值。

OnMouseWheel覆盖只是根据Delta的正负值调用相应的方法。

► 需要 Option Infer On 或小改动

Imports System.ComponentModel
Imports System.Windows.Forms

<DesignerCategory("Code")>
Public Class NumericUpDownPow2
    Inherits NumericUpDown

    Public Sub New()
        Me.Maximum = 64
        Me.Minimum = 1
    End Sub

    Public Overrides Sub UpButton()
        Value = Math.Min(Value * 2, Maximum)
    End Sub

    Public Overrides Sub DownButton()
        Value = Math.Max((Value / 2), Minimum)
    End Sub

    Protected Overrides Sub OnMouseWheel(e As MouseEventArgs)
        Call If(e.Delta > 0, Sub() UpButton(), Sub() DownButton())
        DirectCast(e, HandledMouseEventArgs).Handled = True
        MyBase.OnMouseWheel(e)
    End Sub

    Protected Overrides Sub OnValueChanged(e As EventArgs)
        Dim nearest = CDec(Math.Round(2 ^ Math.Ceiling(Math.Log(Value, 2))))
        Value = Math.Max(Math.Min(nearest, Maximum), Minimum)
        MyBase.OnValueChanged(e)
    End Sub
End Class