programozás iii

19
V 1.0 Programozás III. Automatikus állapotértesítés adatkötéskor (…Changed, INofityPropertyChanged, ObservableCollection<T>, DataTemplate) Adatformázások

Upload: varsha

Post on 04-Jan-2016

57 views

Category:

Documents


2 download

DESCRIPTION

Programozás III. Automatikus állapotértesítés adatkötéskor (…Changed, INofityPropertyChanged, ObservableCollection) Adatformázások Adatkonverziók Erőforrások. Példa. Cél: a személy neve legyen kiírva (adatkötés DataContext állítással), a gombbal lehessen változtatni - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Programozás III

V 1.0

Programozás III.

Automatikus állapotértesítés adatkötéskor(…Changed, INofityPropertyChanged, ObservableCollection<T>, DataTemplate)

Adatformázások

Page 2: Programozás III

V 1.0 ÓE-NIK, 2014

Példa

• Cél: a személy neve legyen kiírva (adatkötés DataContext állítással), a gombbal lehessen változtatni

• Adatkötés a XAML-ben:

2

public MainWindow(){ InitializeComponent(); aktualisSzemely = new Szemely("Piros Péter"); this.DataContext = aktualisSzemely;}

<Label Content="{Binding Nev}"/>

Page 3: Programozás III

V 1.0 ÓE-NIK, 2014

Példa folytatás

• A gomb Click eseménykezelője:

• A konzol kiírás szerint megtörtént a változtatás…

• … az adatkötésben semmi sem látszik!3

private void Button_Click(object sender, RoutedEventArgs e){ aktualisSzemely.Nev = "Kék Péter"; Console.WriteLine(aktualisSzemely.Nev); }

Page 4: Programozás III

V 1.0 ÓE-NIK, 2014

Automatikus állapotértesítés adatkötéskor• Ahhoz, hogy az adatkötések működjenek, a kötés

céljának értesítést kell kapnia a forrás adott tulajdonságának a megváltozásáról– Eddigi kötéseinkben többnyire keretrendszeri osztályok

tulajdonságai voltak a források…• Pl. a Slider Value tulajdonsága volt a forrás, és a Label Content-je a cél• Ezekben meg van oldva, hogy az adatkötés célját értesíteni tudják

– … vagy pedig saját objektum volt a forrás, de csak az adatkötésen keresztül változtattuk benne az adatot

• Pl. a lejátszási listás példaprogramban a Szám típusú objektumok Megjegyzés tulajdonsága volt a forrás, ezt változtatgattuk az adatkötésen keresztül

• Saját objektumaink alapesetben nem küldenek értesítést a változásukról!

4

Page 5: Programozás III

V 1.0 ÓE-NIK, 2014

Automatikus állapotértesítés adatkötéskor• Módszerek:

1. A függőségi tulajdonságok képesek arra, hogy megváltozásukról automatikus értesítést küldjenek. Megoldás: a forrástulajdonság ne sima, hanem függőségi tulajdonság legyen! (nem tárgyaljuk)

2. …Changed esemény kiváltása a tulajdonság változásakor3. INotifyPropertyChanged interfész implementálása

5

Page 6: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – …Changed esemény• A tulajdonság értékének változásakor tüzeljen egy …

Changed esemény (…=tulajdonság neve)• Az eseményre való feliratkozás az adatkötéskor

automatikus

6

public event EventHandler NevChanged;public string Nev{ get { return nev; } set { nev = value; EventHandler nevChanged = NevChanged; if (nevChanged != null) nevChanged(this, EventArgs.Empty); }}

Page 7: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – INotifyPropertyChanged• A tulajdonságot deklaráló osztály implementálja az

INotifyPropertyChanged interfészt (System.ComponentModel)• Ebben egyetlen esemény van

– public event PropertyChangedEventHandler PropertyChanged;• Ez tüzeljen a tulajdonság értékének változtatásakor, az

EventArgs paramétere a tulajdonság neve legyen– string.Empty vagy null, ha az összes tulajdonság megváltozott

7

public string Nev{ get { return nev; } set { nev = value; PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs("Nev")); }}

Page 8: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – INotifyPropertyChanged• Előny az előzőhöz képest: nem kell annyi esemény• Gyakran egynél több tulajdonságnál akarják használni:

OnPropertyChanged()

8

private void OnPropertyChanged(string propertyName){ PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));}

public string Nev{ get { return nev; } set { nev = value; OnPropertyChanged("Nev"); }}

Page 9: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – INotifyPropertyChanged• OnPropertyChanged(), a .NET4.5- ben

9

private void OnPropertyChanged([CallerMemberName] string propertyName=""){ PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));}

public string Nev{ get { return nev; } set { nev = value; OnPropertyChanged(); }}

Page 10: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – Problémák gyűjteményekkel• Gyűjtemény típusú forrástulajdonságnál az

adatkötött GUI-elem (pl. ListBox) a forrásgyűjtemény lecserélését detektálja csak, ha az OnPropertyChanged()-et a setterben hívjuk

• Ez nem detektálja:– Ha a gyűjtemény valamelyik elemét lecseréljük– Add()/Remove()/Insert()…– Ha a gyűjtemény valamelyik elemének egy tulajdonságát

módosítjuk 10

public List<HirlevelFeliratkozas> HirlevelFeliratkozasok{ get { return hirlevelFeliratkozasok; } set { hirlevelFeliratkozasok = value; OnPropertyChanged("HirlevelFeliratkozasok"); //??? }}

Page 11: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – Problémák gyűjteményekkel

11

List<HirlevelFeliratkozas> uj = new List<HirlevelFeliratkozas>();uj.Add(new HirlevelFeliratkozas("gyereknevelés", true));aktualisSzemely.HirlevelFeliratkozasok = uj; //jó aktualisSzemely.HirlevelFeliratkozasok[0] = new HirlevelFeliratkozas("gyereknevelés", true); //nem jóaktualisSzemely.HirlevelFeliratkozasok.Add( new HirlevelFeliratkozas("gyereknevelés", true)); //nem jó

aktualisSzemely.HirlevelFeliratkozasok[0].Aktiv = false; //nem jó

Page 12: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – ObservableCollection<T>• List<T>-hez hasonlóan kell használni

– System.Collections.ObjectModel

• Értesítést küld:– Ha a gyűjtemény valamelyik elemét lecseréljük– Add()/Remove()/Insert()– Elem tulajdonságának módosításakor NEM!

• INotifyCollectionChanged interfészt implementál• Saját osztályaink számára is implementálható, de akkor a fenti esetekre

mind gondolni kell

12

private ObservableCollection<HirlevelFeliratkozas> hirlevelFeliratkozasok;public ObservableCollection<HirlevelFeliratkozas> HirlevelFeliratkozasok{ get { return hirlevelFeliratkozasok; } set { hirlevelFeliratkozasok = value; OnPropertyChanged("HirlevelFeliratkozasok"); //??? }}

Page 13: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – ObservableCollection<T>

13

ObservableCollection<HirlevelFeliratkozas> uj = new ObservableCollection<HirlevelFeliratkozas>();uj.Add(new HirlevelFeliratkozas("gyereknevelés", true));aktualisSzemely.HirlevelFeliratkozasok = uj; //jó aktualisSzemely.HirlevelFeliratkozasok[0] = new HirlevelFeliratkozas("gyereknevelés", true); //jóaktualisSzemely.HirlevelFeliratkozasok.Add( new HirlevelFeliratkozas("gyereknevelés", true)); //jó

aktualisSzemely.HirlevelFeliratkozasok[0].Aktiv = false; //nem jó!

Page 14: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – Fennmaradó problémák• ToString()-es kiírásaink sohasem frissülnek…

– Lehetőleg elkerüljük a használatát!– Helyette: ha Contentben akarjuk kiíratni a „teljes

objektumot” (=több tulajdonság), a Contentbe tartalommenedzsert és abba több vezérlőt teszünk, és ezekhez egyenként adatkötés

– Esetleg ha több vezérlőnél kell, akkor DataTemplate– Vagy ha ListBoxban akarjuk kilistázni az objektumokat, akkor

DataTemplate vagy saját vezérlő…

14

Page 15: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – Fennmaradó problémák• Tulajdonság tulajdonságának változása

– Tulajdonságot pl. tartalommenedzser vagy DataTemplate DataContextjéhez rendelik, altulajdonságokat az abban lévő UI-elemek mutatják

– Vagy komplex Path (pl: {Binding HaziAllat.Harap}) – Vagy gyakran pl. saját vezérlő…

• Gyűjtemény elemének tulajdonságváltozása– Gyakran DataTemplate-ekkel, saját vezérlővel…

• Minden korrekt megoldáshoz kell:– INotifyPropertyChanged implementálása az adatkötésben

felhasznált összes osztályban – ObservableCollection<T> a többi gyűjtemény helyett

15

Page 16: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – Tulajdonság tulajdonságának változása

• Tartalmazó Window DataContext-je a Szemely példány

16

<Label Content="{Binding Nev}"/><Grid DataContext="{Binding Allat}"> <Label Content="{Binding Nev}"/> <Label Content="{Binding Harap}"/></Grid>

class Szemely : INotifyPropertyChanged { … private Allat allat; public Allat Allat { get { return allat; } set { allat = value; OnPropertyChanged("Allat"); } }}

Page 17: Programozás III

V 1.0 ÓE-NIK, 2014

Állapotértesítés – Gyűjtemény elemének tulajdonságváltozása – DataTemplate példa

17

class Szemely : INotifyPropertyChanged{ … private ObservableCollection<HirlevelFeliratkozas> hirlevelFeliratkozasok; public ObservableCollection<HirlevelFeliratkozas> HirlevelFeliratkozasok { get { return hirlevelFeliratkozasok; } set { hirlevelFeliratkozasok = value; OnPropertyChanged("HirlevelFeliratkozasok"); } } //+HirlevelFeliratkozas osztályban is implementálvafy-} //van az INotifyPropertyChanged<ListBox ItemsSource="{Binding HirlevelFeliratkozasok}"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <Label Content="{Binding Tema}"/> <Label Content="{Binding Aktiv}"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate></ListBox>

Az ItemsControloknak az ItemTemplate, a ContentControloknak a ContentTemplate tulajdonságába mehet ilyen DataTemplate, Gridnél CellTemplate… stb.

Page 18: Programozás III

V 1.0 ÓE-NIK, 2014

Feladat

• HF: az összeállított pizza ListBox-ba való helyezése• HF: Az összeállított pizzák file-ba történő elmentése,

illetve betöltése

18

Page 19: Programozás III

V 1.0 ÓE-NIK, 2014

Feladat

19