Blog (215)
Komentarze (3.1k)
Recenzje (1)

Tworzymy własny ValueConverter, czyli najbardziej przydatny obiekt w bindowaniu danych do widoku (XAML/C#)

Strona główna@djfoxerTworzymy własny ValueConverter, czyli najbardziej przydatny obiekt w bindowaniu danych do widoku (XAML/C#)
01.06.2016 01:57

Zapewne tworząc aplikacje w WPF czy UWP natknęliście się na to, że właściwość w modelu (ViewModelu) wymagała konwersja na inny typ lub inną wartość, aby móc jej użyć na widoku. Tworzenie jednak dodatkowych właściwości jest nieefektywne i zbędne.

Z pocą przychodzi interfejs IValueConverter, który konwertuje jedne dane na drugie, bez konieczność rozszerzania obiektu. W moim przypadku musiałem przekwaterować status notyfikacji NotificationStatus (New, Old, Unknown) na Opacity (nieprzezroczystość).

Na widoku nowe powiadomienia nie są przezroczyste, zaś stare mają przezroczystość ustawioną na 0.5. Efekt jest następujący:

217482

Oczywiście najbardziej używanym konwerterem jest: Bool Visibility, czyli mając zmienną o typu Bool(true/false), chcemy sterować widocznością elementu (Visibility.Visible/Visibility.Collapsed).Przejdźmy jednak do naszego przykładu.

bDUMxGYD

Zamiast tworzyć nową właściwość, szybko tworzymy klasę implementującą interfejs IValueConverter.

public sealed class StatusToOpacityConverter : IValueConverter{    public object Convert(object value, Type targetType, object parameter, string language)    {        NotificationStatus status = (NotificationStatus)value;        if (status == NotificationStatus.New)        {            return 1;        }        else        {            return 0.5;        }    }

public object ConvertBack(object value, Type targetType, object parameter, string language) { throw new NotImplementedException(); } } /code

Interfejs IValueConverter wymaga implementacji dwóch metod: Convert i ConvertBack.Pierwsza z nich implementuje konwersję danych z obiektu na dane niezbędne do użycia na widoku, zaś druga robi to w odwrotną stronę.

bDUMxGYJ

W naszym przypadku zadanie jest proste. Powiadomienie ze statusem NotificationStatus.New nie może być przezroczyste, zaś notyfikacje z innymi statusami mają otrzymać przezroczystość 0.5. Zmienna value jest zawsze typu NotificationStatus, więc bez dodatkowej zabawy rzutujemy ją na ten typ i zwracamy int określający przezroczystość.

Możemy skorzystać również ze zmiennej targetType, z typem zmiennej wynikowej. Dodatkowo parameter może zawierać dodatkowe informacje przesłane do konwertera z widoku. Ważnym parametrem jest także zmienna language, która określa język aplikacji w chwili konwersji, do wykorzystania, gdy konwersja zależna jest od używanego języka (np. zamiana daty na string).

W drugą stronę konwersja przebiega podobnie z tym, że dane wejściowe i wyjściowe są zamienione. W omawianym przypadku na wejściu mielibyśmy zmienną int, a typem wynikowym byłby NotificationStatus.

Jednakże nie jest to nam potrzebne, gdyż łączenie (bindowanie) w tym przypadku obiektu (z danymi) z widokiem odbywa się w jedną stronę (one-way binding).

bDUMxGYK

Na widoku, czyli w pliku XAML, konwertera użyjemy w następujący sposób:

(...)

Oczywiście obiekt przekazany do widoku ma właściwość Status o typie NotificationStatus.

Na końcu pamiętajmy jeszcze o rejestracji StatusToOpacityConverter w App.xaml:

bDUMxGYL
            (...)            
DePesza dostępna jest w markecie Windows 10 (desktop i mobile). Bezpośredni link: DePesza.

Aktualne źródła można znaleźć na GitHub pod adresem: https://github.com/djfoxer/dp.notification

bDUMxGZz