A felhőalapú technológiákra váltás egy izgalmas kihívás - ha tudod miként kezdj neki! Ebben a cikkben szeretném megosztani...
IValueConverter: Háttérlogika az adatkötéshez
Gulyás GáborA napokban merült fel egy probléma az egyik hallgatótársam részéről. Egy adott osztályban van egy változó, melynek értéke alapján szeretnénk változtatni valamit a felületen: jelenjen meg egy elem, legyen más a háttérszíne, bármi. Írhatunk különböző Triggereket ennek elérésére, azonban egy másik koncepciót mutatnék ma be nektek.
Az IValueConverter – mint az a nevéből is adódik – egy interfész, mely két függvényt implementál:
object Convert(Object, Type, Object, CultureInfo);
object ConvertBack(Object, Type, Object, CultureInfo);
- Object: Az objektum, amit szeretnénk konvertálni
- Type: Milyen típusra szeretnénk konvertálni
- Object: Paraméter, amivel akár befolyásolhatjuk a konvertálás eredményét
- CultureInfo: Ezt a CultureInfo-t fogja használni a Converter (CultureInfo befolyásolja például a tizedesjegy elválasztó karaktert is)
Az interfészek definíciója alapján mindkét függvényt definiálnunk kell, utóbbit azonban ha nem használjuk, általában egy NotImplementedException();-t szoktam benne hagyni. A Convert függvény az első paraméterén keresztül kapja meg a konvertálásra váró értéket, vagy ami alapján a logikánkat le szeretnénk futtatni. Visszatérési értékként bármit megadhatunk, azonban emiatt érdemes következetesnek lennünk a névválasztás során, így mindig tudni fogjuk milyen értéket is vár a Converter és mit ad vissza.
Általában a következő koncepciót követem: InputTypeToOutputTypeConverter. Például: BooleanToVisibilityConverter, vagy HexToSolidColorConverter.
Lássunk egy kódpéldát:
BooleanToVisibilityConverter
Sűrűn előforduló probléma, hogy egy boolean típusú érték alapján szeretnénk megjeleníteni, vagy éppen elrejteni egy felületi elemet. A következő Converter ezt fogja megvalósítani:
public class BooleanToVisibilityConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool val = (bool)value;
return (val) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
A ConvertBack függvényt eddig még egyszer sem volt szükségem implementálni, ugyanis nem volt szükségem visszaalakításra.
A Converter használatához a következőket kell megtenni:
- A XAML kódban meg kell határoznunk egy új névteret, mely a kódunkban a Converter névterére mutat. Pl.: xmlns:conv=”Appunk.Nevtere.Converters”
- Az oldal erőforrásai között definiáljuk statikus erőforrásként a Converter-t:
<Page.Resources> <conv:BooleanToVisibilityConverter x:Key="BooleanToVisibility" /> </Page.Resources>
- Tetszőleges felületi elem Visibility paraméterén alkalmazzunk egy adatkötést, azon pedig Converter-nek adjuk meg az erőforrást:
<Button Content="Belépés" Visible="{Binding IsValid, Converter={StaticResource BooleanToVisibility}}" />
Fontos tudni, hogy ez a megoldás csak abban az esetben működik, ha az adatkötésben résztvevő osztályon implementáltunk az INotifyPropertyChanged interfészt, vagy használjuk az MVVM Light ObservableObject, illetve ViewModelBase osztályát és a változó értékének módosításakor jelezzük is a felület irányába ezt a módosítást. Amennyiben ezt nem tesszük meg, a felületen az eredeti érték marad használatban és a konvertálás nem fut le újból.
A Converter működése a paraméterrel befolyásolható. Ide bármilyen statikus értéket megadhatunk, adatkötés viszont nem használható. A paraméter mezővel például az előző Converter működését megfordíthatjuk: igaz érték esetén elrejtjük a felületi elemet, hamis érték esetén pedig megjelenítjük. Ehhez a következőképpen módosítjuk a kódot:
public class BooleanToVisibilityConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool val = (bool)value;
if (parameter == null)
{
return (val) ? Visibility.Visible : Visibility.Collapsed;
}
else
{
return (val) ? Visibility.Collapsed : Visibility.Visible;
}
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Ekkor a Converter a következőképpen használva pont a fordított eredményt adja majd:
<Button Content="Belépés" Visible="{Binding IsValid, Converter={StaticResource BooleanToVisibility}, ConverterParameter='inverted'}" />
A ConverterParameter értékeként igazából bármit átadhatunk ebben az esetben, csupán azt figyeljük, hogy null az érték vagy sem – alapértelmezetten a ConverterParameter értéke null.
Kérdésed van? Tedd fel bátran!