vb.net 隐藏 NumericUpDown 控件上的向上/向下按钮
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19517661/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Hiding up/down buttons on NumericUpDown control
提问by Wine Too
I am trying to subclass NumericUpDown in several ways to get better functionality and appearance.
我正在尝试以多种方式对 NumericUpDown 进行子类化,以获得更好的功能和外观。
Since NUD is construct of two controls I would like to hide up/down buttons in cases where property "Increment" is set to 0.
由于 NUD 是由两个控件构成的,我想在属性“增量”设置为 0 的情况下隐藏向上/向下按钮。
This code is in subclass:
此代码在子类中:
Protected Overrides Sub OnTextBoxResize(ByVal source As Object, ByVal e As System.EventArgs)
Controls(0).Hide()
End Sub
... and it work OK. But in that function I cannot check a value of Increment property like this:
...它工作正常。但在该函数中,我无法检查 Increment 属性的值,如下所示:
Protected Overrides Sub OnTextBoxResize(ByVal source As Object, ByVal e As System.EventArgs)
If Me.Increment = 0 Then
Controls(0).Hide()
End if
End Sub
In scope of this function Me is not reachable. I am also try with using local variables but can't find which event is fired before OnTextBoxResize to read value of Increment property.
在此功能范围内,我无法访问。我也尝试使用局部变量,但找不到在 OnTextBoxResize 之前触发哪个事件以读取 Increment 属性的值。
What to do in such case to get desired functionality?
在这种情况下该怎么做才能获得所需的功能?
采纳答案by LarsTech
This seems to work fairly well. It Shadows the Increment property in order to set the visibility of the spinner controls when the Increment value is being changed. There is an underlying private method the base control calls called PositionControlswhich you cannot stop — that method could create some flicker, but on my test, it didn't.
这似乎工作得很好。它隐藏 Increment 属性,以便在更改 Increment 值时设置微调控件的可见性。基础控制调用有一个底层私有方法PositionControls,您无法停止该方法——该方法可能会产生一些闪烁,但在我的测试中,它没有。
Public Class MyNumBox
Inherits NumericUpDown
Shadows Property Increment As Decimal
Get
Return MyBase.Increment
End Get
Set(value As Decimal)
MyBase.Increment = value
OnTextBoxResize(Me, EventArgs.Empty)
End Set
End Property
Protected Overrides Sub OnHandleCreated(e As EventArgs)
MyBase.OnHandleCreated(e)
OnTextBoxResize(Me, EventArgs.Empty)
End Sub
Protected Overrides Sub OnTextBoxResize(source As Object, e As EventArgs)
If Me.IsHandleCreated Then
Me.Height = Me.PreferredHeight
Me.Controls(0).Visible = (MyBase.Increment > 0)
Dim borderWidth As Integer = 0
If Me.BorderStyle > BorderStyle.None Then
borderWidth = SystemInformation.Border3DSize.Width
End If
Dim textWidth As Integer
If Me.Increment = 0 Then
textWidth = Me.ClientSize.Width - (borderWidth * 2)
Else
textWidth = Me.ClientSize.Width - Me.Controls(0).Width - (borderWidth * 2)
End If
If Me.UpDownAlign = LeftRightAlignment.Left Then
If Me.Increment = 0 Then
Me.Controls(1).SetBounds(borderWidth, borderWidth, _
textWidth, Me.Controls(1).Height)
Else
Me.Controls(1).SetBounds(borderWidth + Me.Controls(0).Width, _
Me.Controls(1).Top, textWidth, Me.Controls(1).Height)
End If
Else
Me.Controls(1).SetBounds(borderWidth, Me.Controls(1).Top, _
textWidth, Me.Controls(1).Height)
End If
Me.Refresh()
End If
End Sub
End Class
In the OnTextBoxResize override, I am re-positioning the controls into their proper place, and this version does account for the UpDownAlign property.
在 OnTextBoxResize 覆盖中,我将控件重新定位到适当的位置,并且此版本确实考虑了 UpDownAlign 属性。
回答by Idle_Mind
If you can, read this threadover at EE where I answered a similar question. It resizes the edit portion so that the control is redrawn correctly when the buttons have been hidden and the control is resized. *Otherwise the portion of the control where the buttons used to be leaves ghosts behind.
如果可以,请在 EE 上阅读此主题,在那里我回答了类似的问题。它调整编辑部分的大小,以便在隐藏按钮和调整控件大小时正确重绘控件。*否则以前按钮所在的控件部分会留下鬼影。
One solution to your specific problem is to wait for the VisibleChanged() event and check the Increment() property from there. Here is a conversion of my previous answer with some minor changes:
您的特定问题的一种解决方案是等待 VisibleChanged() 事件并从那里检查 Increment() 属性。这是我以前的答案的转换,有一些小的变化:
Public Class NoArrowNumericUpDown
Inherits NumericUpDown
Private itb As InnerTextBox = Nothing
Protected Overrides Sub OnVisibleChanged(e As System.EventArgs)
If Me.Visible Then
If Me.Increment = 0 AndAlso IsNothing(itb) Then
Dim ctl As Control = Me.Controls(0) ' get the spinners
Me.Controls.Remove(ctl) ' remove the spinners
ctl = Me.Controls(0) ' get the edit control
itb = New InnerTextBox(Me, ctl)
End If
End If
MyBase.OnVisibleChanged(e)
End Sub
Public Class InnerTextBox
Inherits NativeWindow
Private parentControl As Control = Nothing
Const WM_WINDOWPOSCHANGING As Integer = &H46
Public Sub New(parentControl As Control, InnerTextBox As Control)
Me.parentControl = parentControl
Me.AssignHandle(InnerTextBox.Handle)
End Sub
Protected Overrides Sub WndProc(ByRef m As Message)
Select Case m.Msg
Case WM_WINDOWPOSCHANGING
Dim wp As WindowPos = CType(System.Runtime.InteropServices.Marshal.PtrToStructure(m.LParam, GetType(WindowPos)), WindowPos)
If Me.parentControl IsNot Nothing Then
wp.cx = Me.parentControl.ClientSize.Width - 2 * wp.x
wp.cy = Me.parentControl.ClientSize.Height
System.Runtime.InteropServices.Marshal.StructureToPtr(wp, m.LParam, True)
End If
Exit Select
End Select
MyBase.WndProc(m)
End Sub
Public Structure WindowPos
Public hwnd As IntPtr
Public hwndInsertAfter As IntPtr
Public x As Integer
Public y As Integer
Public cx As Integer
Public cy As Integer
Public flags As UInteger
End Structure
End Class
End Class
EDIT: You could just enclose your code in a Try/Catch block?
编辑:您可以将代码包含在 Try/Catch 块中吗?
Public Class NoArrowNumericUpDown
Inherits NumericUpDown
Protected Overrides Sub OnTextBoxResize(ByVal source As Object, ByVal e As System.EventArgs)
Try
If Me.Increment = 0 Then
Controls(0).Hide()
End If
Catch ex As Exception
End Try
End Sub
End Class

