NumericUpDown, который допускает только диапазон значений степени двойки

У меня есть NumericUpDown, минимальное значение которого равно 1, а максимальное — 64. Мне нужно увеличить его от 1 до 64, используя значения степени 2, поэтому оно должно быть 1, 2, 4, 8, 16, 32, 64.

Я пробовал несколько способов изменить приращение NUD, но без удовлетворительных результатов.
Как мне решить эту проблему?


person The Eng    schedule 25.03.2021    source источник


Ответы (2)


Если вы уменьшите размер текстовой части элемента управления NumericUpDown, чтобы он не был виден, вы можете поместить текстовое поле только для чтения рядом с ним, чтобы оно выглядело так, как будто оно является его частью, а затем...

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

Возможно, вы захотите изменить цвет границы TextBox: текстовое поле.

person Andrew Morton    schedule 25.03.2021
comment
Я бы выбрал ответ Джими, если это нечто большее, чем разовый. - person Andrew Morton; 25.03.2021

Я предлагаю использовать пользовательский элемент управления, полученный из NumericUpDown, чтобы вы могли внутренне обрабатывать события изменения значения, которые генерируются различными возможными действиями: нажатие кнопок вверх/вниз, вращение колеса мыши, ввод числа вручную, привязки данных и т. д.

Переопределение метода OnValueChanged имеет последнее слово: если представленное значение не соответствует критериям (является степенью двойки в указанном диапазоне), число изменяется на ближайшее (более высокое) допустимое значение.

Переопределение OnMouseWheel просто вызывает соответствующий метод, основанный на положительном или отрицательном значении дельты.

► Требуется 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
person Jimi    schedule 25.03.2021