270 likes | 365 Views
Programming III. XML XAML Data Binding I. XML (w3schools.com). <? xml version="1.0"?> < bookstore > < book category =" COOKING "> < title lang =" en "> Everyday Italian </ title > < author > Giada De Laurentiis </ author > < year > 2005 </ year > < price > 30.00 </ price >
E N D
ProgrammingIII. XML XAML Data Binding I.
XML (w3schools.com) • <?xml version="1.0"?> • <bookstore> • <bookcategory="COOKING"> • <titlelang="en">Everyday Italian</title> • <author>Giada De Laurentiis</author> • <year>2005</year> • <price>30.00</price> • </book> • <bookcategory="WEB"> • <titlelang="en">Learning XML</title> • <author>Erik T. Ray</author> • <year>2003</year> • <price>39.95</price> • </book> • </bookstore> • A hierarchical way of defining data • XML declaration+ elements+ attributes • Elements: <bookstore>, <book>, <title> … • Attributes: <book>-bancategory=„…” …
XML • Strict parser rules • First line: optional format descriptor with character encoding:<?xml version="1.0" encoding="ISO-8859-1"?><?xml version="1.0" encoding="UTF-8"?> • Every element can contain: • Text content or sub elements • Attributes • There has to be a root element without sibling (in this example, the <bookstore> element) • Every tag must be closed (<tag></tag> vagy <tag />) • Every tag must be properly nested • BAD: <a><b></a></b> • GOOD: <a><b></b></a> • Case sensitive • Everything depends on the interpretation
XAML (eXtensibleApplicationMarkupLanguage) • XML-based description of object states and hierarchy between .NET objects • We can use classes that can be instantiated and that contain a default constructor • Anything that is in the XAML can also be expressed in C# • In WPF we use XAML to build our GUI • During the compile process • msbuild.exewill compile it into binary data, then add the data as a resource into the assembly– .g.cs -> .baml • The InitializeComponent() will load it
XAML • XAML format: • C# format: • In XAML, the elements mean creation of an instance • The attributes specify the properties/events <CheckBoxContent="Automatikus mentés" Name="checkBox1" IsChecked="True" Checked="checkBox1_Checked"/> CheckBox checkBox1 = newCheckBox(); checkBox1.Content = "Automatikus mentés"; checkBox1.IsChecked = true; checkBox1.Checked += checkBox1_Checked;
XAML– setting the textual content • With an attribute: • <Typename.Propertyname> sub-element: • As a text sub-element A XAML specifikációja szerint: minden osztály deklarálhat „tartalomtulajdonságot” (Content Property) – ekkor a közvetlen gyermekelem ennek a beállítására szolgál. A ContentControloknál ez a „tartalomtulajdonság” a Content… <CheckBoxContent="Automatikus mentés" Name="checkBox1"IsChecked="True"/> <CheckBox Name="checkBox1"IsChecked="True"> <CheckBox.Content> Automatikus mentés </CheckBox.Content> </CheckBox> <CheckBoxName="checkBox1"IsChecked="True"> Automatikus mentés </CheckBox>
XAML – setting the complex content • As a sub-element • <Typename.Propertyname> sub-element • Syntax error – The Scrollbar is not a ContentControl, there is no Content <CheckBox Name="checkBox1"IsChecked="True"> <Button>Automatikus mentés</Button> </CheckBox> <CheckBox Name="checkBox1"IsChecked="True"> <CheckBox.Content> <Button>Automatikus mentés</Button> </CheckBox.Content> </CheckBox> <ScrollBarName="scrollBar1"> <Button>Automatikus mentés</Button> </ScrollBar>
XAML – setting the complex content • … withItemsControl descendants, sub-elements go into the Items (Collection Syntax) • … with Panel (content managers), sub-elements go into the Children <ListBox > <Button Content="Button" Width="75"/> <Button Content="Button" Width="75"/> <Button Content="Button" Width="75"/> </ListBox> <Window... Title="MainWindow" Height="350" Width="525"> <Grid> <Button Content="Button"Width="75" .../> <Button Content="Button"Width="75" .../> <Button Content="Button"Width="75" .../> </Grid> </Window> Gyűjteményszintaxis (Collection Syntax)
XAML • AttachedPropertySyntax <Grid> <Grid.RowDefinitions> <RowDefinition Height="107*"/> <RowDefinition Height="115*"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="66*"/> <ColumnDefinition Width="67*"/> </Grid.ColumnDefinitions> <Button Content="Button1" Grid.Column="0" Grid.Row="0"/> <Button Content="Button2" Grid.Column="1" Grid.Row="0"/> <Button Content="Button3" Grid.Column="0" Grid.Row="1"/> </Grid>
XAML namespaces <Window x:Class="WpfApplication4.MainWindow” xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid> </Grid> </Window> • XML namespaces define the allowed xml tags and attributes and keywords
XAML namespaces <Window x:Class="WpfApplication4.MainWindow” xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ... • WPF-centered.NET namespaces are imported: • System.Windows • System.Windows.Controls • System.Windows.Data • System.Windows.Media • System.Windows.Navigation ... stb. • This is the default namespace, no need for extra namespace prefix: <Window x:Class="WpfApplication4.MainWindow” xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Grid></Grid> </Window>
XAML namespaces <Window x:Class="WpfApplication4.MainWindow” xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" ... • XAML-specific keywords and the System.Windows.Markuptypes are imported: • Class, Null, Static, Array, ClassModifier, FieldModifier, DynamicResource, StaticResource, Key, Name, Code, … • We will use only a few special keywords from this namespace • We have to use the namespace prefix for these keywords (usually, x:Something ) <Window x:Class="WpfApplication4.MainWindow” x:ClassModifier="internal" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525"> <Button Content="START!" Name="buttonStart” x:FieldModifier="public"/> </Window>
XAML namespaces • Import a custom .NET namespace • clr-namespace: namespace_name • assembly: the executing assembly that contains the namespace, typically .exe/.dll file without the extension • Refer to the documentation: <Window x:Class="WpfApplication4.MainWindow" ... xmlns:System="clr-namespace:System;assembly=mscorlib”> <x:Array Type="System:String"> <System:String>Hello</System:String> <System:String>World</System:String> </x:Array> </Window>
XAML markup extensions • Assign special, highly complex values for a XAML attribute, usually defined as string and converted into a primitive/complex type • Customize behaviour: • Use Null • Assign an already existing object • Assign a static value • We want to use a type that does not have a default parameterless constructor • etc. • Format: • For every attribute, the allowed keywords between the {} letters are different – must be careful! Property="{…}"
Data binding I. • Connect any property of a GUI element to another instance • When the instance changes, the GUI should change as well • When the GUI changes, the instance should change as well • MVVM, we will almost use MVVM • E.g.: • Display the data of a person: • textBoxName.Text person.Name • checkBoxOnHoliday.IsCheckedperson.OnHoliday • checkBoxSick.IsCheckedperson.Sick
Data binding I. • E.g.: • Volume slider • label.Content slider.Value • E.g. : • Set the enabled property of multiple controls based on a single checkbox • radioButtonXXX.IsEnabled checkBox.IsChecked • OR: stackPanel.IsEnabled checkBox.IsChecked
Data bindingI. • E.g. : • Display certain elements in a listbox • listBox.ItemsSource tömb • E.g. : • Change the border based on the selected item • listBox.BorderBrush listBox.SelectedItem • E.g. : • Display extra data about the selected item • labelXXXX.Content comboBox.SelectedItem.XXXX
Data BindingI. • Every data binding has a source and a target • The source is where the data is stored, it has to be a public property of any class • The target is usually a property of a GUI element that will use the data • The target must be a DependencyProperty • The target class must be a DependencyObject descendant • E.g. : • Display thedata of a person: • textBoxName.Textperson.Name • Source: person.Name • Target: textBoxName.Text
Data Binding I. • XAML using the {Binding} markup extension • ElementName:if the source is another UI element • Path:the name of the property inside the source • Alternative syntax • Equivalent to the following C# code (NEVER USE) • E.g. in the constructor or in the Loaded event handler <CheckBoxName="checkBoxEnabled"Content="Enable!"/> <TextBoxName="textBoxToEnable" IsEnabled="{BindingElementName=checkBoxEnabled,Path=IsChecked}"/> "{BindingIsChecked,ElementName=checkBoxEnabled}" textBoxToEnable.SetBinding(TextBox.IsEnabledProperty, newBinding("IsChecked") { Source= checkBoxEnabled });
Data Binding I. – Defining paths • Simple property inside the source: • ElementName=checkBoxEnabled, Path=IsChecked • Property of a property: • ElementName=listBox, Path=SelectedItem.Name • Indexer property: • ElementName=listBox, Path=Items[0]
Data Binding I. - DataContext • Default source of a data binding • The DataContextis a dependency property, so its value can be “received/inherited” from the parent UI element / XAML tag • We use this quite often: <StackPanel Name="stackPanel" DataContext="{BindingElementName=comboBoxPeople,Path=SelectedItem}"> <Label Content="{BindingName}"/> <Label Content="{BindingAge}" <Label Content="{BindingCountry}"/> <Label Content="{BindingCity}"/> </StackPanel>
Data Binding I. - DataContext • We can set the DataContextetfrom C# code: • XAML code: • Setting the source: <StackPanelName="stackPanel" > <LabelContent="{BindingName}"/> <LabelContent="{BindingAge}" <LabelContent="{BindingCountry}"/> <LabelContent="{BindingCity}"/> </StackPanel> Szemelysz = newSzemely("Péter", 12, "Magyarország", "Budapest"); stackPanel.DataContext= sz;
Data Binding I. - DataContext • Sometimes we specify a Data Binding to a whole object • Path is not present or Path=. • The whole DataContext is used • Automatic ToString() is called not advised publicoverridestringToString() //SzemélyosztályToString() { returnnev + " (" + szuletesiEv + ")"; } publicMainWindow() { InitializeComponent(); this.DataContext= newSzemely() { Nev = "Peti", SzuletesiEv = 1985 }; } <Label Content="{Binding}"/>
Data Binding I. • Possible directions • OneWay, TwoWay, OneWayToSource, OneTime • OneWay:the change in the source will change the target, the target will not change the source • OneWayToSource:the change in the target will change the source, the source will not change the target • TwoWay:vice-versa • OneTime:one-time initialization from source to target, no synchronization is done afterwards <TextBoxText="{Binding Value, ElementName=slider,Mode=TwoWay}"
Data Binding I. • When to update the source? • If the direction is TwoWayor OneWayToSource • LostFocus (default for TextBox) • PropertyChanged (usually default) • Explicit:only if UpdateSource() is called • Default(LostFocus/ProperyChanged/Explicit) <TextBoxText="{Binding Value, ElementName=slider, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Searching for errors... • We get notifications only in the Output window and only when the data is actually requested • No exception is thrown • Use trace: http://www.wpf-tutorial.com/data-binding/debugging/ • Same message for bad names and non-public properties!