Poruszany temat możemy wykorzystać zarówno w przypadku Silverlight jak i WPF. W obu przypadkach cała procedura przebiega w taki sam sposób. Przykład dla odmiany pokażę w WPF jednak tak jak wcześniej pisałem w Silverlight wszystko przebiega w taki sam sposób.
Rozpoczniemy od napisania przykładowej aplikacji:
Aplikacja pobiera dane z bazy danych AdventureWorksLT którą można pobrać ze stron microsoftu jako przykłady baz danych wraz z testowymi danymi danymi.
Kod który jest wymagany aby utworzyć pokazaną aplikację:
Klasa Product:
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace WpfApplication1 { public class Product { public string Name { get; set; } public string Color { get; set; } public decimal StandardCost { get; set; } public DateTime SellStartDate { get; set; } } }
Klasa DataAccess:
Code:
Okno:
Code:
Warstwa prezentacji (XAML):
Code:
Tak więc podstawowe "klocki" tworzące naszą aplikację są gotowe. Co w tej aplikacji nie podoba się na pierwszy rzut oka? Kilka rzeczy:
- design
- Standard Cost - 4 miejsca po przecinku zamiast standardowo dwóch
- Sell Stard Date - źle sformatowana data - mało czytelne
- nazwy kolumn
W tym poście zajmiemy się dwoma środkowymi problemami.
Aplikacja, którą napisaliśmy korzysta ze standardowego schematu:
1. Pobierz dane z bazy
2. Wyświetl dane użytkownikowi.
Taki schemat ma w domyśle niejawnie zapisane - dane są prawidłowe oraz są odpowiednio sformatowane. Oczywiście rzadko zdarza się pracować na idealnych danych. Dlatego aby poradzić sobie z sytuacjami, w których musimy dokonać obróbki wyświetlanych danych, WPF wprowadza nowe narzędzia w porównaniu do WindowsForms:
- string formatting - bardzo prosta a zarazem użyteczna właściwość pod nazwą Binding.StringFormat. Pozwala na zdecydowanie w jaki sposób będą wyświetlane ciągi znakowe.
- value converters - pozwala na dowolną konwersję między różnymi typami danych i zwracanie ich do bindowanej kontrolki
String Formatting
Pierwszy omawiany typ formatowania (string formatting) pozwala w łatwy sposób modyfikować łańcuchy tekstowe. Ustawienie właściwości Binding.StringFormat można zdefiniować do instrukcji:
{0:X} - gdzie 0 to pierwszy argument a X to format który chcemy zaaplikować dla danego tekstu.
W naszym pierwszym przypadku, czyli wyświetlania waluty możemy zastosować format:
{0:C} - gdzie C to standardowy sposób wyświetlania waluty w danym regionie. Wynik będzie następujący:
Kod formatujący dane wygląda następująco:
Code:
Dodając jedną właściwość, uzyskaliśmy pożądany wygląd. Warto zrwrócić na zastosowanie pustych nawiasów {}. Taki zabieg wymagany jest tylko w wypadku, gdy wartość właściwości StringFormat zamierzamy rozpocząć od nawiasu klamrowego. W innym przypadku np. StringFormat=Value is {0:C} - nawiasy nie są potrzebne.
Inne przydatne sposoby formatowania:
P - procenty
F[n] - formatuje liczbę rzeczywistą, zaokrąglając ją do n znaków po przecinku
d - krótka data
D - długa data
Value converter
Value converter to dużo bardziej zaawansowane narzędzie do konwersji typów. Pozwala na skonwertowanie jednego typu do dowolnego innego. Przykładów gdzie można użyć takiego zabiegu można sporo znaleźć w codziennej pracy:
- konwersja danych do postaci znakowej
- tworzenie specyfinczego typu dla WPF (np. z danych w postaci binarnej tworzyć obraz)
- zmiana właściwości w zależności od konwertowanej wartości - np. podświetlając na czerwono komórkę w wypadku błędnych danych.
Kroki które należy przejść aby skorzystać z dobrodziejstwa tej technologi są następujące:
1. Tworzymy klasę implementującą interfejs IValueConverter.
2. Dodajemy do stworzonej klasy atrybut ValueConversion, mówiący o typie z którego jest konwertowana wartość na docelowy typ.
3. Implementujemy metodę Convert, która zmienia typ wejściowy na żądany typ do wyświetlenia.
4. Implementujemy metodę ConvertBack, która definiuje jak ma zostać zmieniona wartość w drugą stronę - np. jak ma zostać zapisana do bazy danych
Zobaczmy więc przykład związany z konwersją daty.
Na początek klasa konwertujące, stworzona według podanych wyżej zasad:
Code:
Samo użycie sprowadza się do stworzenia obiektu konwertera i przypisaniu go do odpowiedniej właściwości podczas bindowania:
Code:
Efekt ostateczny:
W tym przypadku skorzystaliśmy z prostego zamienienia daty z jednego formatu na inny. Jednak w codziennej pracy można zetknąć się z innymi ciekawymi zagadnieniami:
- pobranie danych z bazy w formacie binarny i zamiana ich na obrazek
- zmiana koloru komórki w gridzie, elementu listy itp. na podstawie aktualnej wartości