WPF umożliwia łatwą konwersję danych prezentowanych w GUI.
IValueConverter
Interfejs ten implementujemy aby konwertować pojedynczą wartość.
Definicja interfejsu jest następująca:
Code:
public interface IValueConverter
{
object Convert(object value, Type targetType, object parameter, CultureInfo culture);
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture);
}
Metody zawarte w tym interfejsie:
- Convert - konwertuje dane wejściowe do żądanego typu
- ConvertBack - odwraca konwersję do pierwotnego typu
W większości przypadków konwersja wsteczna nie jest możliwa, z tego względu nie implementuje się metody
ConvertBack.Obowiązkowo musimy ją zaimplementować gdy będziemy wykorzystywać bindowanie w obie strony (
TwoWay).
Klasa która będzie implementować ten interfejs musi zostać oznaczona atrybutem
ValueConversion który mówi z jakiego typu do jakiego następuje konwersja.
Przykład konwertera:
Code:
namespace WpfExample
{
[ValueConversion(typeof(DateTime), typeof(string))]
public class DataConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.GlobalizationCultureInfo culture)
{
var dateTime = (DateTime?)value;
if (dateTime.HasValue)
{
return dateTime.Value.ToString("dd-MM-yyyy");
}
return "";
}
public object ConvertBack(object value, Type targetType, object parameter, System.GlobalizationCultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Aby użyć tak napisanego konwertera:
- w XAML-u definiujemy przestrzeń nazw gdzie znajduje się nasz konwerter
- tworzymy obiekt naszego konwertera, np w zasobach okna
- stworzoną instancję przypisujemy do właściwości Converter
Przykład:
Code:
<Window x:Class="WpfExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfExample"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:DataConverter x:Key="DataConverter" />
</Window.Resources>
<Grid>
<TextBlock
HorizontalAlignment="Left" VerticalAlignment="Top"
Text="{Binding CurrentDateTime, Mode=OneWay, Converter={StaticResource DataConverter}}"/>
</Grid>
</Window>
Praktyczny przykład konwertera to pobranie z bazy ścieżek do plików graficznych i wyświetlenie ich w aplikacji jako grafiki.
Innym przykładem może być translacja całych napisów. Metody Convert i ConvertBack zawierają referencje do obiektu reprezentującego obecnie wybraną kulturę. Jeżeli aplikacja będzie miała działać w kilku językach w łatwy sposób możemy stworzyć tłumaczenie napisów na odpowiedni język.
Przykład:
Code:
[ValueConversion(typeof(string), typeof(string))]
public class LanguageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var textToTranslate = (string) value;
var translatorService = new TranslatorService();
switch (culture.ToString())
{
case "en-US":
return translatorService.PolishToEnglish(textToTranslate);
case "fr-FR":
return translatorService.PolishToFrench(textToTranslate);
default:
return textToTranslate;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var textToTranslate = (string)value;
var translatorService = new TranslatorService();
switch (culture.ToString())
{
case "en-US":
return translatorService.EnglishToPolish(textToTranslate);
case "fr-FR":
return translatorService.FrenchToPolish(textToTranslate);
default:
return textToTranslate;
}
}
}
IMultiValueConverter
Interfejs ten umożliwia tworzenie konwerterów które konwertują wartości z kilku pól w jedną. Przykładem takiej operacji może być obliczanie ceny za kilka sztuk towaru. Mnożymy wtedy dane z pól ilość oraz cena za sztukę.
Interfejs ten posiada tak samo jak
IValueConverter dwie metody do konwersji:
Code:
public interface IMultiValueConverter
{
object Convert(object[] values, Type targetType, object parameter, CultureInfo culture);
object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture);
}
Różnica między tymi dwoma interfejsami jest tak, iż ten drugi przyjmuje w metodzie
Convert tablicę obiektów, a w metodzie
ConvertBck zwraca tablicę obiektów, a jako parametr przychodzący - tablicę typów.
Przykład:
Code:
namespace WpfExample
{
public class TotalPriceConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.GlobalizationCultureInfo culture)
{
var count = (int)values[0];
var price = (decimal)values[1];
return (count * price).ToString("C");
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.GlobalizationCultureInfo culture)
{
throw new NotImplementedException();
}
}
}
XAML:
Code:
<Window x:Class="WpfExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfExample"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<local:TotalPriceConverter x:Key="TotalPriceConverter" />
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="Amount: "/>
<TextBlock Text="{Binding Count}"/>
</StackPanel>
<StackPanel Grid.Row="1" Orientation="Horizontal">
<TextBlock Text="Price: "/>
<TextBlock Text="{Binding UnitPrice}"/>
</StackPanel>
<StackPanel Grid.Row="2" Orientation="Horizontal">
<TextBlock Text="Amount: "/>
<TextBlock>
<TextBlock.Text>
<MultiBinding Converter="{StaticResource TotalPriceConverter}">
<Binding Path="Count" />
<Binding Path="UnitPrice" />
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Grid>
</Window>
Brak komentarzy:
Prześlij komentarz