2010-12-03 2 views
0

나는 이걸 만들고 싶다. WinForm 컨트롤 (NumericUpDown)은 내가 일하고있는 것의 타입 (전체 대 플로팅)에 따라 조건부로 전체 숫자를 시행한다.DecimalPlaces = 0 일 때 System.Windows.Forms.NumericUpDown에서 숫자가 아닌 숫자를 입력 할 수 없게하는 방법은 무엇입니까?

DecimalPlaces = 0을 설정하면 0이 표시되고 위/아래를 클릭하면 1이 증가/감소합니다. 그러나 0.6을 입력하면 1로 표시되지만 0.6으로 유지됩니다. 이후에 증가 시키면 기본 값이지만 표시되지 않는 값은 1.6이됩니다.

나는 내가 원하는 것을 시행 할 수있는 간단하고 관용적 인 방법을 찾고있다. (바라건대 내가 원하는 것은 분명하다.) 일종의 이벤트를 가로 챌 필요가 있다면 그럴 것입니다. 그러나 NumericUpDown 클래스가 이미 제공하는 플래그/설정에만 의존하기를 바랍니다.

솔루션에 하위 클래스 NumericUpDown이 포함되는 경우이를 고려해야합니다. 이 단계에서 나는 다른 곳에서 버그를 일으킬 수있는 깔끔한 변경에 대한 문서화 된 해킹을 선호합니다. NumericUpDown을 하위 분류하지 않을 수있는 옵션을 원합니다.

질문이 있으시면 알려주세요. 고마워.

답변

1

기본 값은 십진 형식입니다. DecimalPlaces는 컨트롤에 표시되는 자릿수에만 영향을줍니다. 원하는 것을 얻는 가장 쉬운 방법은 NumericUpDown.Value를 정수로 반올림하는 것입니다.

+0

Andrei, 어떻게 구체적으로 할 수 있습니까? 좀 더 정확하게 - 어떤 이벤트를 차단해야합니까? 사용자가 비 정수 값을 입력 할 수 있다고 생각하기를 원하지 않습니다. 나는 값을 반올림 할 수는 있지만 0.7을 입력 할 수 없도록하고 싶다. 검증을 실패하기를 바란다. –

+0

값을 반올림해야합니다. 또는 이벤트를 가로 채고 싶다면 (작은 해킹 추가), ValueChanged 이벤트를 가로 챌 수 있습니다. 여기에서 무한 루프를 피하기 위해 값을 라운드 부분으로 수정하십시오 (아직 반올림되지 않은 경우에만!). –

+0

흠 ... TextChanged 이벤트를 해킹하는 것보다 낫지 않습니까? 값을 자동으로 수정하고 싶지 않습니다. 사용자가 입력을 받아들이지 않는다는 것을 어떻게 든 알기를 바랍니다. –

0

여기에 우리가 사용하고있는 불완전한 해결책이 있습니다. ,

Private Sub HandleKeyPress(sender As Object, e As Windows.Forms.KeyPressEventArgs) Handles MyNumericUpDown.KeyPress 
    If e.KeyChar = "."c Then e.Handled = True 
End Sub 

둘째 자리 이외의 다른 붙여 넣기에서 사용자를 방지 첫째, 소수 (사용자가 입력 할 수 있습니다 다른 모든 잘 컨트롤 자체에 의해 처리 될 것으로 보인다)를 입력에서 사용자를 방지 할 수 있습니다. 내가 취한 접근법은 몇 가지 특정 키 조합 (ctrl-v 및 shift-insert)을 하드 코드로 사용한다는 점에 유의하십시오. 사용자가 붙여 넣을 수있는 다른 방법 (예 : up-down 컨트롤의 상황에 맞는 메뉴 사용)은 처리하지 않습니다.

Protected Overrides Function ProcessCmdKey(ByRef msg As System.Windows.Forms.Message, 
              ByVal keyData As System.Windows.Forms.Keys) As Boolean 
    If keyData = (Keys.Shift Or Keys.Insert) OrElse keyData = (Keys.Control Or Keys.V) Then 
    Dim data As IDataObject = Clipboard.GetDataObject 
    If data Is Nothing Then 
     Return MyBase.ProcessCmdKey(msg, keyData) 
    Else 
     Dim text As String = CStr(data.GetData(DataFormats.StringFormat, True)) 
     If text = String.Empty Then 
      Return MyBase.ProcessCmdKey(msg, keyData) 
     Else 
      For Each ch As Char In text 
       If Not Char.IsNumber(ch) Then 
       Return True 
       End If 
      Next 
      Return MyBase.ProcessCmdKey(msg, keyData) 
     End If 
    End If 
    Else 
    Return MyBase.ProcessCmdKey(msg, keyData) 
    End If 
End Function 

이것은 완벽한 해결책은 아니지만, 우리가 필요로하는 행동에 충분히 근접합니다.

관련 문제