Strona używa cookies (ciasteczek). Dowiedz się więcej o celu ich używania i zmianach ustawień. Korzystając ze strony wyrażasz zgodę na używanie cookies, zgodnie z aktualnymi ustawieniami przeglądarki.    X

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

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:

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.

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(); } }

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ę.

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).

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

<Grid Opacity="{ Binding Status, Converter={StaticResource StatusToOpacityConverter}, Mode=OneWay }" >(...)</Grid>

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:

<Application (...) xmlns:helpers="using:djfoxer.dp.notification.App.Helpers"> <Application.Resources> (...) <helpers:StatusToOpacityConverter x:Key="StatusToVisibilityConverter" /> </Application.Resources> </Application>

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
 

windows oprogramowanie programowanie

Komentarze

0 nowych
tylko_prawda   10 #1 01.06.2016 06:18

Efekt jest chyba nawet lepszy niż to, co jest na dobreprogramy.pl - tam jest tylko wyszarzanie.
PS Czy na wersji mobilnej można masowo usunąć komentarze?

djfoxer   17 #2 01.06.2016 07:02

@tylko_prawda: Dzięki ;) Można usuwać za jednym zamachem tylko te przeczytane.

tylko_prawda   10 #3 01.06.2016 15:14

@djfoxer: Przydałoby się usuwanie wszystkich komentarzy, jak na dobrychprogramach przeglądarkowych... używam tylko wersji stacjonarnej DePeszy, bo nie mam Lumii, ale takim czymś bym nie pogardził.

djfoxer   17 #4 01.06.2016 17:42

@tylko_prawda: Jest do zrobienia, na pewno dodam :)