IntTextBox oraz RealTextBox w WPF

Poprawnie zaprojektowana aplikacja powinna weryfikować dane w każdej warstwie systemu. Oczywiście najważniejszym miejscem jest warstwa biznesowa ale dobrym zwyczajem jest walidacja również w warstwie prezentacji. W idealnym interfejsie użytkownik nie jest w stanie wprowadzić błędnych danych. Podstawowym przykładem są pola edycyjne w których powinno się wpisać np. ilość sprzedanego produktu. Użytkownik nie powinien mieć możliwości wprowadzenia tekstu w takie pole.

Zacznijmy od prostej sprawy – akceptacja tylko cyfr.

public class IntNumberTextBox:System.Windows.Controls.TextBox
{
    protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
    {
        e.Handled = !ValidateText(e.Text);
        base.OnPreviewTextInput(e);
    } 
    private bool ValidateText(string text)
    {
        foreach (Char character in text)
        {
            if (System.Char.IsDigit(character) == false)
                return false;
        }
        return true;
    }
}

Jak widać wystarczy tylko przeładować metodę OnPreviewTextInput i ustawić flagę Handled na true w przypadku gdy wprowadzony znak jest niedozwolony.

W przypadku liczb rzeczywistych musimy umożliwić dodatkowo wprowadzanie przecinków lub kropek. Znak oddzielający część dziesiętną od całkowitej zależy od ustawień regionalnych w systemie operacyjnym. W C# możemy sprawdzić jaki to jest znak za pomocą właściwości System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator.

public class RealNumberTextBox:System.Windows.Controls.TextBox
{
   protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
   {
       e.Handled = !ValidateText(e.Text);
       base.OnPreviewTextInput(e);
   }
   private bool ValidateText(string text)
   {
       if ( text == System.Globalization.NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
                  return true;
       foreach (Char character in text)
       {
           if (System.Char.IsDigit(character) == false)
               return false;
       }
       return true;
   }
}

Inne ciekawe wartości, zależne od ustawień regionalnych, które są przydatne w walidacji to m.in CurrencyDecimalSeparator, CurrencyGroupSeparator, CurrencySymbol, NegativeSign, NegativeInfinitySymbol.

Teraz pozostało nam tylko wykorzystać nowo utworzoną kontrolkę w pliku XAML. Najpierw należy zadeklarować przestrzeń nazw:

<Window x:Class="Sample.Views.Product.Product"
        xmlns:controls="clr-namespace:Sampple.Controls"
        inne deklaracje
>

Następnie korzystamy z kontrolki w sposób analogiczny do standardowych kontrolek:

<controls:IntNumberTextBox HorizontalAlignment="Left" Width="200" Text="tekst" />

Pamiętajmy, że walidacja w dolnych warstwach jest zwykle wolniejsza ponieważ należy połączyć się najpierw np. z bazą danych lub z usługą sieciową. Ponadto korzystanie z aplikacji z walidacją w warstwie prezentacji jest po prostu łatwiejsze dla użytkownika.

Leave a Reply

Your email address will not be published.