Vázání dat Data Binding Ing. Petr Voborník, Ph.D.
Vázání dat Datové objekty implementují rozhraní INotifyPropertyChanged Ovládací prvky editovanou hodnotu provážou s vlastností objektu přes Binding Hodnotu lze během editace v ovládacím prvku konvertovat přes IValueConverter Vlastní ovládací prvky, potomky třídy BindableObject, mohou mít své propojitelné vlastnosti
Datové objekty Rozhraní INotifyPropertyChanged pro datové objekty Přes událost PropertyChanged oznamuje okolí, že došlo ke změně hodnoty vlastnosti Tuto událost je potřeba volat v set-kódu vlastností public class Osoba : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged([CallerMemberName] string propName = null) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName)); private string jmeno; public string Jmeno { get { return jmeno; } set { jmeno = value; OnPropertyChanged(); } }
Provázání objektu s ovládacím prvkem v1 V XAMLu se do editované vlažnosti ovládacího prvku zapíše {Binding Jmeno} Přes C# se buď přímo tomuto prvku nebo některému z kontejnerů, ve kterém se nachází, nastaví BindingContext na objekt, hodnoty jehož vlastností se mají editovat XAML <StackLayout x:Name="sLayout"> <Entry Text="{Binding Jmeno}" /> </StackLayout> C# var osoba = new Osoba { Jmeno = "Alois" }; sLayout.BindingContext = osoba;
Provázání objektu s ovládacím prvkem v2 Provázání se přes {Binding...} nemusí provést pouze přes XAML, ale jde to i v C# Pro ovládací prvek se zavolá metoda SetBinding s parametry určujícími jaká její vlastnost se provazuje a názvem vlastnosti datového objektu, která se s editorem má provázat var eJmeno = new Entry(); eJmeno.SetBinding(Entry.TextProperty, "Jmeno"); var osoba = new Osoba { Jmeno = "Alois" }; eJmeno.BindingContext = osoba;
Další parametry vázání dat Mode – BindingMode: OneWay, OneWayToSource, TwoWay StringFormat – parametrický formát ("Ahoj {0}!") Converter – konverze hodnot... <StackLayout x:Name="sLayout"> <Entry Text="{Binding Jmeno, Mode=TwoWay}" /> <Label Text="{Binding Jmeno, Mode=OneWay, StringFormat='Jméno: {0}'}" /> </StackLayout>
Provázání dvou prvků bez datového objektu Vlastnosti ovládacích prvků lze provázat i bez nutnosti existence datového objektu Jeden prvek pak hodnotu umožňuje měnit, druhý ji může třeba „nějak“ zobrazovat Provázání se nastaví v C#, kdy zdrojem hodnot (BindingContext) pro zobrazující prvek je prvek umožňující změnu hodnoty XAML <StackLayout> <Slider x:Name="sProcent" Minimum="0" Maximum="100" Value="20" /> <Label x:Name="lProcent" /> </StackLayout> C# lProcent.SetBinding(Label.TextProperty, "Value", stringFormat: "{0}%"); lProcent.BindingContext = sProcent;
Konverze hodnot Třída implementuje rozhraní IValueConverter s metodami Convert – převod hodnoty z objektu pro editor ConvertBack – převod hodnoty z editoru pro objekt public class IntToStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) return System.Convert.ToString(value); // int => string } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) if (int.TryParse(value as string, out int result)) // string => int return result; return 0;
Konverze hodnot – použití Třída implementuje rozhraní IValueConverter s metodami Convert – převod hodnoty z objektu pro editor ConvertBack – převod hodnoty z editoru pro objekt <StackLayout x:Name="sLayout"> <StackLayout.Resources> <ResourceDictionary> <local:IntToStringConverter x:Key="cIntToStr" /> </ResourceDictionary> </StackLayout.Resources> <Entry Text="{Binding Vek, Mode=TwoWay, Converter={StaticResource cIntToStr}}" /> <Label Text="{Binding Vek, Mode=OneWay, StringFormat='Věk: {0:N0} let'}" /> </StackLayout>
Vlastní ovládací prvek s propojitelnou vlastností Třída ovládacího prvku dědí z třídy BindableObject (nebo jejího potomka) Statická položka s názvem vlastnosti a příponou Property definovaná přes BindableProperty Vlastnost v get používá předkovu metodu GetValue a v set metodu SetValue Změnu hodnoty oznámí událost propertyChaged, kde lze změnu promítnout do ovládacího prvku public partial class EditorBarvy : BindableObject { public static readonly BindableProperty BarvaProperty = BindableProperty.Create("Barva", typeof(Color), typeof(EditorBarvy), Color.White, propertyChanged: BarvaChanged); private static void BarvaChanged(BindableObject bindable, object oldValue, object newValue) { if ((Color)oldValue != (Color)newValue) ((EditorBarvy)bindable).bNahledBarvy.BackgroundColor = (Color)newValue; } public Color Barva get { return (Color)GetValue(BarvaProperty); } set { if (Barva != value) SetValue(BarvaProperty, value); }
Souhrn INotifyPropertyChanged – pro datové objekty Binding / SetBinding – provázání vlastnosti ovládacího prvku a datového objektu IValueConverter – konverze editovaných hodnot BindableObject – vlastní ovládací prvek s propojitelnou vlastností