WPF Data Binding Detailed Introduction _ Practical Tips

Source: Internet
Author: User
Tags prototype definition xpath

Overview of WPF Data binding

Data binding: The process of establishing a connection between the application UI and the business logic. If the binding is set correctly and the data provides proper notification, the visual elements bound to the data automatically reflect the changes when the value of the data changes. Data binding may also mean that the underlying data can be automatically updated to reflect changes if the external representation of the data in the visual element changes.

For example, if a user edits a value in a TEXTBOX element, the underlying data value is automatically updated to reflect the change.

1. Data binding involves two aspects:

One is the binding source and one is the binding target. The binding source is the source data used by the control bindings, which is the control that the data displays.

2. For a binding source, the following four types can be in WPF:

CLR object: Can be bound to a exposed property, child property, indexer of a CLR class.
ADO. NET objects: such as DataTable, DataView, and so on.
XML file: Parsing using XPath.
DependencyObject: Binds to its dependency property, which is the control-bound control.
For a binding target, it must be a dependencyobject in WPF that binds data to its dependency property.

second, the pattern of binding

1. Depending on the direction of the data flow, data binding in WPF is divided into the following four categories:

OneWay binding: Changes to the Source property automatically update the target property, but changes to the target property do not propagate back to the source property. This binding type applies to situations where the bound control is an implicitly read-only control.

TwoWay binding: Changes to the Source property automatically update the target property, and changes to the target property automatically update the Source property. This binding type applies to editable forms or other fully interactive UI scenarios.

OneWayToSource is the opposite of oneway; it updates the Source property when the target property changes.

Onetime binding: This binding causes the Source property to initialize the target property, but does not propagate subsequent changes.

Note: If you do not need to monitor changes to the target property, using the oneway binding pattern avoids the overhead of twoway binding mode.

Most properties default to OneWay bindings, but some dependency properties, typically properties of the control that the user can edit, such as the Text property of the TextBox and the IsChecked property of the CheckBox, default to TwoWay binding.

If you want to know whether a dependency property binding is one-way or bidirectional by default, you can use GetMetaData to get property metadata for the property, and then check the Boolean value of the Bindstwowaybydefault property.

Sample code:

Copy Code code as follows:



<page x:class= "Wpfdemo.page1"

Xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"

Title= "Page1" horizontalalignment= "Center" >

<grid name= "gridtable" height= "360" background= "Silver" >

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<columndefinition width= "130" ></ColumnDefinition>

<columndefinition width= "></ColumnDefinition>"

<columndefinition width= "></ColumnDefinition>"

</Grid.ColumnDefinitions>

<label width= "130" height= "grid.row=" "0" grid.column= "0" name= "Label1" >TwoWay</Label>

<textbox width= "height=" "grid.row=" 0 "grid.column=" 1 "name=" textBox4 "text=" {Binding elementname= Scrollbar1,path=value,mode=twoway} "/>

<label width= "130" height= "grid.row=" "1" grid.column= "0" name= "Label2" >OneWay</Label>

<textbox width= "height=" "grid.row=" 1 "grid.column=" 1 "name=" TextBox1 "text=" {Binding elementname= SCROLLBAR1, Path=value,mode=oneway} "/>

<label width= "130" height= "grid.row=" "2" grid.column= "0" name= "label3" >OneWayToSource</Label>

<textbox width= "height=" "grid.row=" 2 "grid.column=" 1 "name=" TextBox2 "text=" {Binding elementname= SCROLLBAR1, Path=value,mode=onewaytosource} "/>

<label width= "130" height= "grid.row=" "3" grid.column= "0" name= "label4" >OneTime</Label>

<textbox width= "height=" "grid.row=" 3 "grid.column=" 1 "name=" TextBox3 "text=" {Binding elementname= SCROLLBAR1, path=value,mode=onetime} "/>

<scrollbar value= "minimum=" 0 "grid.rowspan=" 4 "grid.row=" 0 "grid.column=" 2 "maximum=" Name= "ScrollBar1" Width= "height=" {Binding elementname=gridtable,path=height} "/>

</Grid>

</Page>




Based on the results of the program implementation, we can get the following conclusions:

For oneway bindings: The data displayed in the interface can vary with the value of the data source, but changing the interface's data does not affect the data source.

For TwoWay bindings: Data displayed in the interface and data sources can be displayed and updated in two directions.

For OneWayToSource bindings: The initial interface's data is empty, and changing the interface's data can affect the value of the data source, but changing the data source value is not reflected in the interface.

For onetime bindings: The initial value of the data source displayed in the interface, changing the value of the data source does not change the interface's data display, and changing the interface's data does not affect the data source.

binding target values affect binding source value conditions

Question: Is the value of the binding source updated while you are editing the text, or is it not updated until you finish editing the text and remove the mouse pointer from the text box? Or do you need to update it in a manual update?

1. The UpdateSourceTrigger property is the reason for determining the trigger source update.

The point of the right arrow in the following illustration shows the role of the UpdateSourceTrigger property:

TwoWay and OneWayToSource are bound by the binding target to the binding source direction, and if the value change that implements the binding target affects the value of the binding source, you only need to set the UpdateSourceTrigger value of the appropriate control binding, with a value of three:

PropertyChanged: Updates the binding source immediately when the binding target property changes.

LostFocus: Updates the binding source when the bound target element loses focus.

Explicit: The binding source is updated only when the Updatesource method is invoked.

Note: The default value of the UpdateSourceTrigger value for most dependency properties is propertychanged, and the default value for the Text property is LostFocus.

2. Example

Copy Code code as follows:



Xaml:


<page x:class= "Wpfdemo.changed"

Xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"

title= "Changed" >

<grid name= "gridtable" height= "background=" Silver ">"

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<columndefinition width= "></ColumnDefinition>"

<columndefinition width= "></ColumnDefinition>"

<columndefinition width= "></ColumnDefinition>"

</Grid.ColumnDefinitions>

<textblock grid.row= "0" width= "height=" grid.column= "0" name= "Label1" text= "propertychanged:" ></ Textblock>

<textblock grid.row= "1" width= "height=" grid.column= "0" name= "Label2" text= "LostFocus:" ></textblock >

<textblock grid.row= "2" width= "height=" grid.column= "0" name= "label3" text= "Explicit:" ></textblock >

<textbox grid.row= "0" width= "height=" "text=" {Binding path=username,mode=twoway,updatesourcetrigger= propertychanged} "grid.column=" 1 "name=" TextBox1 "/>

<textbox grid.row= "1" width= "height=" "text=" {Binding path=username,mode=twoway,updatesourcetrigger= LostFocus} "grid.column=" 1 "name=" TextBox2 "/>

<textbox grid.row= "2" width= "height=" "text=" {Binding path=username,mode=twoway,updatesourcetrigger= EXPLICIT} "grid.column=" 1 "name=" txtexplicit "/>

<textblock grid.row= "3" width= "height=" "grid.column=" 0 "name=" lblresult "text=" Result: "></TextBlock>

<textblock grid.row= "3" width= "height=" "grid.column=" 1 "name=" Lbldisplay "text=" {Binding Path=username,mode =oneway} "></TextBlock>

<button name= "btnchanged" width= "" height= "" grid.row= "3" grid.column= "2" >Explicit</Button>

</Grid>

</Page>




Copy Code code as follows:



C#:


Namespace Wpfdemo

{

public partial class Changed:page

{

#region Properties

Public Usermodel CurrentUser

{

Get;set;

}

#endregion

#region Constructor

Public Changed ()

{

InitializeComponent ();

This. Loaded + = new Routedeventhandler (changed_loaded);

This.btnChanged.Click + = new Routedeventhandler (Btnchanged_click);

}

#endregion

#region changed_loaded

void Changed_loaded (object sender, RoutedEventArgs e)

{

This. CurrentUser = new Usermodel () {username= "SWD"};

This. DataContext = this. CurrentUser;

}

#endregion

#region btnLogon_Click

void Btnchanged_click (object sender, RoutedEventArgs e)

{

This.txtExplicit.GetBindingExpression (Textbox.textproperty). Updatesource ();

}

#endregion

}

public class Usermodel

{

public string UserName

{

Get;set;}

}

}




Program execution results as described above.


Iv. Data-Provider

1. XmlDataProvider:

XmlDataProvider access to XML data is available in the following three ways:

You can embed inline XML data using the XmlDataProvider class.

You can set the Source property to the Uri of the XML data file.

You can set the Document property to XmlDocument.

Note: When the Xmldocument.nodechanged event occurs, XmlDataProvider performs a full refresh of all bindings. A specific node is not optimized.

By default, the Xmldataprovider.isasynchronous property is set to true, which means that by default XmlDataProvider retrieves data and asynchronously generates a collection of XML nodes.

The following is an introduction to displaying XML data using the three methods described above:

Example

Copy Code code as follows:



Xaml:


<page x:class= "Wpfdemo.xmlbinding"

Xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"

Title= "xmlbinding" xmlns:local= "Clr-namespace:wpfdemo" >

<Page.Resources>

<xmldataprovider x:key= "XmlFile" source= "Students.xml" xpath= "/students" ></XmlDataProvider>

<xmldataprovider x:key= "Innerxmlstu" xpath= "/students" >

<x:XData>

<students xmlns= "" >

<Student><name>swd</name></Student>

<Student><name>awd</name></Student>

<Student><name>asd</name></Student>

</Students>

</x:XData>

</XmlDataProvider>

</Page.Resources>

<Grid>

<Grid.RowDefinitions>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

<RowDefinition></RowDefinition>

</Grid.RowDefinitions>

<Grid.ColumnDefinitions>

<columndefinition width= "></ColumnDefinition>"

<columndefinition width= "></ColumnDefinition>"

</Grid.ColumnDefinitions>

<textblock grid.row= "0" grid.column= "0" height= "+" width= "M" text= "Reference XML file" ></TextBlock>

<textblock grid.row= "1" grid.column= "0" height= "a" width= "M" text= "Embedded xml" ></TextBlock>

<textblock grid.row= "2" grid.column= "0" height= "+" width= "M" text= "Dynamic XML" ></TextBlock>

<listbox name= "lisbxmlfile" grid.row= "0" grid.column= "1" height= "width=" "itemssource=" {Binding source={ StaticResource Xmlfile},xpath=student/name} ">

</ListBox>

<listbox name= "Lisbinnerxml" grid.row= "1" grid.column= "1" height= "width=" "itemssource=" {Binding source={ StaticResource Innerxmlstu},xpath=student/name} ">

</ListBox>

<listbox name= "Lisbxmldoc" grid.row= "2" grid.column= "1" height= "width=" "itemssource=" {Binding xpath= Student/name} ">

</ListBox>

</Grid>

</Page>




Copy Code code as follows:

Xml:


<?xml version= "1.0" encoding= "Utf-8"?>

<Students>

<Student>

<name>swd</name>

<score>110</score>

</Student>

<Student>

<name>asd</name>

<score>120</score>

</Student>

<Student>

<name>awd</name>

<score>130</score>

</Student>

</Students>


From the above example I think we should be very easy to understand and apply.




2. ObjectDataProvider:

ObjectDataProvider enables you to create objects in XAML that can be used as binding sources and provides you with the following properties to execute a query on an object and bind to the result.

Use the Constructorparameters property to pass parameters to the object's constructor.

Use the MethodName property to invoke a method.

Use the Methodparameters property to pass the argument to the method. You can then bind to the result of the method.

Use objecttype to specify the object that will provide the data binding source.

Use the ObjectInstance property to specify an existing object instance as the source

Note: You can also use the Isasynchronous property to specify whether object creation is performed on a worker thread or in the active context. That is, whether to retrieve data asynchronously.

Example:

Copy Code code as follows:



Xaml:

C#:


Namespace Wpfdemo

{

#region Cobjectdataprovider

public partial class Cobjectdataprovider:page

{

Public Cobjectdataprovider ()

{InitializeComponent ();}

}

#endregion

#region Country

public class Country

{

#region Name

public string Name

{Get;set;}

#endregion

#region Provincelist

Public list<province> Provincelist

{Get;set;}

#endregion

#region getallcity

public static list<country> getallcity ()

{

return new list<country>{

New Country

{

Name = "China",

Provincelist = new List<province>

{

New province{name= "Fujian province",

Citylist=new list<city>{new city{name= "Fuzhou"},new city{name= "Xiamen City"},new city{name= "Zhangzhou"},new City{Name= "Quanzhou"}

},

New Province{name= "Jiangsu province",

Citylist=new list<city>{

New City{name= "Suzhou"},new city{name= "Nanjing"},new city{name= "Yangzhou"},new city{name= "Wuxi"}}

},

New Province{name= "Jiangxi province",

Citylist=new list<city>{new city{name= "Nanchang"},new city{name= "Jiujiang"}}}

}

};

}

#endregion

}

#endregion

#region Province

public class Province

{

#region Name

public string Name

{Get;set;}

#endregion

#region CityList

Public list<city> CityList

{Get;set;}

#endregion

}

#endregion

#region City

public class city

{

#region Name

public string Name

{Get;set;}

#endregion

}

#endregion

}


V. Type conversion and data validation

1. IValueConverter interface

Provides a way to apply custom logic to bindings.

At binding time, the data source object to the target object (or to the target object to the data source object) may require some kind of conversion. Only the IValueConverter interface custom value Converter can be implemented.

Interface Prototype Definition:

public interface IValueConverter
{
Object Convert (object value, Type targettype, object parameter, CultureInfo culture);
Object Convertback (object value, Type targettype, object parameter, CultureInfo culture);
}

The parameter value is the value to convert, Typetarget is the converted value type, and parameter is the parameter passed by the converterparameter of the binding class.

Convert method: The data binding engine calls this method when it propagates a value from the binding source to the binding target.

Convertback method: This method is called when the data binding engine propagates a value from a binding target to a binding source.

The Valueconversion property is used to tell the type of source and target data that the custom converter class can convert (the Valueconversion property will be seen in the later example).

2. ValidationRule class

Provides a way to create a custom rule to check the validity of user input.

ValidationRule: base class for all custom validation rules. Provides a portal for user-defined validation rules.

Exceptionvalidation: Represents a rule that checks for exceptions that are thrown during the binding source property update. It is a built-in rule that checks for exceptions that are thrown during the binding source property update.

Validationresult: The presentation of data validation results. After the Validate method of the ValidationRule object is executed, the validationresult is used to represent the result of the validation. This contains the error message-errorcontent, and whether the data is valid-isvalid. Validresult is a valid instance of Validationresult.

ValidationError: Represents a validation error that is created by the binding engine when ValidationRule reports validation errors.

Copy Code code as follows:



Xaml:


<page x:class= "Wpfdemo.typeconvertandvalidationrule"

Xmlns= "Http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x= "Http://schemas.microsoft.com/winfx/2006/xaml"

Title= "Typeconvertandvalidationrule"

xmlns:src= "Clr-namespace:wpfdemo" >

<grid height= "width=" "360" background= "Silver" >

<Grid.RowDefinitions>
<RowDefinition>
</RowDefinition>
<RowDefinition>
</RowDefinition>
<RowDefinition>
</RowDefinition>
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition>
</ColumnDefinition>
<ColumnDefinition>
</ColumnDefinition>
</Grid.ColumnDefinitions>

<textblock height= "width=" text= "Birthday" grid.row= "0" grid.column= "0" ></TextBlock>

<textbox name= "Txtbirthday" height= "width=" grid.row= "0" grid.column= "1" >

<TextBox.Text>

<binding path= "Birthday" updatesourcetrigger= "LostFocus" mode= "TwoWay" >

<Binding.ValidationRules><src:ValidationDateTimeRule/></Binding.ValidationRules>

<Binding.Converter><src:MyConverterOfBirthFormat/></Binding.Converter>

</Binding>
</TextBox.Text>

<TextBox.ToolTip>
<binding relativesource= "{RelativeSource Self}" path= (Validation.errors) [0]. Errorcontent "></Binding>
</TextBox.ToolTip> </TextBox>

<textblock height= "width=" grid.row= "1" text= "{Binding path=birthday,mode=oneway}" grid.column= "1" > </TextBlock>

<textblock height= "width=" text= "e-mail format check" grid.row= "2" grid.column= "0" ></TextBlock>

<textbox height= "width=" grid.row= "2" grid.column= "1" >

<TextBox.Text>

<binding path= "EMail" >

<binding.validationrules><exceptionvalidationrule/></binding.validationrules>

</Binding> </TextBox.Text>

<TextBox.ToolTip>

<binding relativesource= "{RelativeSource Self}" path= (Validation.errors) [0]. Errorcontent "></Binding>

</TextBox.ToolTip> </TextBox>

</Grid>

</Page>




Copy Code code as follows:



C#:


Namespace Wpfdemo

{

#region Typeconvertandvalidationrule

public partial class Typeconvertandvalidationrule:page

{

Public Typeconvertandvalidationrule ()

{

InitializeComponent ();

This. DataContext = new UserInfo {Name = "swd", Birthday =system.convert.todatetime ("1987/10/21"), EMail = "swd@126.com"};

}

}

#endregion

#region UserInfo

public class UserInfo

{

#region Name

public string Name

{Get;set;}

#endregion

#region Birthday

Public DateTime Birthday

{Get;set;}

#endregion

#region EMail

private string Email;

public string EMail

{

Get

{return email;}

Set

{

This.email = value;

Regex r = new Regex (@ "^\w+" ([-+.] \w+) *@\w+ ([-.] \w+) *\.\w+ ([-.] \w+) *$ ");

if (!r.ismatch (value))

{

throw new ApplicationException ("email format is wrong!") ");

}

}

}

#endregion

}

#endregion

Binding Collection Objects

1. Icollectionview interface

Allows collections to have the current records management, custom sorting, filtering, and grouping features. such as sorting, grouping, filtering, navigating, and other custom views, and this does not affect the actual storage of your background data.

2. ObservableCollection <T> class

Represents a Dynamic data collection that provides notifications when items are added, removed, or the entire list is refreshed.

3. Overview of the WPF MVVM

MVVM (Model-view-viewmodel) is evolved from MVC,MVP. MVVM separates the logic from the interface and frees the business logic.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.