2015-05-28 15 views
8

Ho creato un controllo NumericUpDown esadecimale per sotto-classing il NumericUpDown base e aggiungendo il seguente metodo:creazione di un controllo NumericUpDown esadecimale

protected override void UpdateEditText() 
{ 
    this.Text = "0x" + ((int) Value).ToString("X2"); 
} 

Questo funziona abbastanza bene. Il controllo ora mostra i valori nel formato:

0x3F

che è esattamente quello che cercavo.

Ma una cosa mi preoccupa: ogni volta che il testo -property è assegnato, un System.FormatException viene generata. Questo non sembra influenzare la funzionalità del controllo, ma penso che sia brutto.

Questo è il top della stack:

MyAssembly.dll HexNumericUpDown.UpdateEditText() Linea 31 C# System.Windows.Forms.dll System.Windows.Forms.NumericUpDown.ValidateEditText!() Unknown System.Windows.Forms.dll! System.Windows.Forms.UpDownBase.Text.set (valore stringa) Unknown

Posso semplicemente ignorare questa eccezione? O c'è un modo pulito per sbarazzarsi di questo?

+0

Avete forse qualcosa in esecuzione sull'evento TextChanged che tenta di convertire la stringa in un numero intero? – Jens

+0

"ogni volta che viene assegnata la proprietà Text, viene lanciata una System.FormatException" ma dove? Pubblica lo stacktrace. –

+0

Fatto. Ho aggiunto la traccia dello stack. – Boris

risposta

6

È necessario eseguire l'override del metodo ValidateEditText() in modo da poter gestire correttamente il prefisso "0x" (facoltativo).E sostituisci UpdateEditText() al prefisso "0x". Aggiungi una nuova classe al tuo progetto e incolla il codice mostrato di seguito. Compilare. Drop il nuovo controllo dalla parte superiore della casella degli strumenti nel form:

using System; 
using System.Windows.Forms; 

class HexUpDown : NumericUpDown { 
    public HexUpDown() { 
     this.Hexadecimal = true; 
    } 

    protected override void ValidateEditText() { 
     try { 
      var txt = this.Text; 
      if (!string.IsNullOrEmpty(txt)) { 
       if (txt.StartsWith("0x")) txt = txt.Substring(2); 
       var value = Convert.ToDecimal(Convert.ToInt32(txt, 16)); 
       value = Math.Max(value, this.Minimum); 
       value = Math.Min(value, this.Maximum); 
       this.Value = value; 
      } 
     } 
     catch { } 
     base.UserEdit = false; 
     UpdateEditText(); 
    } 

    protected override void UpdateEditText() { 
     int value = Convert.ToInt32(this.Value); 
     this.Text = "0x" + value.ToString("X4"); 
    } 
} 

FWIW, il try eccentrico/catch-em-tutto viene direttamente dalla versione di .NET. L'ho tenuto per fare in modo che il controllo si comportasse allo stesso modo. Modifica l'argomento ToString() nel modo desiderato.

0

C'è una differenza tra il casting e ConvertTo:

(int)obj - questo è un cast esplicito di obj al tipo int, si indica al compilatore che obj è un int. Se obj non è un tipo int, otterrai un'eccezione cast. Ma non è REALMENTE un int. e il formato X2 ha bisogno di veri int i.

Convert.ToInt32(obj) - Questa è una chiamata esplicita alla classe Convert per restituire una rappresentazione int di oggetto.

A causa di ciò è necessario utilizzare Convert.ToInt32(Value)

MA in MSDN che dice:

1) Questa API (numericUpDown.Text) sostiene il infrastruttura .NET Framework e non è destinato per essere usato direttamente dal tuo codice.

2) Il testo non ha alcun effetto sull'aspetto del controllo NumericUpDown ; pertanto, è nascosto nel designer e da IntelliSense.

+0

che non risolvere il problema. L'eccezione si verifica quando il valore è assegnato alla proprietà Testo. L'int-casting non causa un'eccezione. – Boris

+0

this.Text, che cos'è "questo"? –

+0

Questo è il controllo NumericUpDown. – Boris

0

immagino è inoltre necessario eseguire l'override del metodo ParseEditText ValidateEditText, per accettare il valore esadecimale e impostare la proprietà Value per il valore int corretto.

+0

'ParseEditText' non è virtuale ma ValidateEditText è –

Problemi correlati