In-depth introduction to WPF (7)-data green channel, binding (on)

Source: Internet
Author: User

In-depth introduction to WPF (7)-data green channel, binding (on)

Small order:

How can I jump from 2 to 7 ?! Ah, I am really sorry. I have been too busy recently, and the reason for my busy work is also very simple-my technology is too bad and there are still many things to learn. Outside the door, it is found that a very important skill for professional programmers is to read the code written by others. This skill is even more important than writing code by yourself. Anstinus is a master of code reading. I wrote the code that he knew at first glance and was able to modify immediately, after reading his code for several days, I still don't know how it happened.

Between 2 and 7 are reserved for the basis of The XAML language. Some articles have been written soon, but if I am not satisfied with them, they will never be posted online. At the same time, many friends have been urging me to write down recently. In a hurry, I had to catch up with the most important sections and stick them up first.

Therefore, from this article, the following articles are almost the core content of WPF and are very important. These articles introduceBinding, Dependency Property, routed event & command. Stay tuned!


When learning new things, people are always used to comparing them with the old knowledge they already know so that they can grasp the new things quickly and remember deeply. Therefore, some people often ask me: "What is the biggest difference between WPF and Windows form? Please let me know in the simplest words ." Okay, this is a very good question. It seems that the biggest difference between WPF and winform is like the previous XAML language, but XAML is just a superficial phenomenon, the "data-driven interface" is a real fascinating feature of WPF that differentiates it from winform ". Around this core, WPF has prepared a lot of cutting-edge technologies, including The XAML prepared for the interface, the dependency property prepared for the underlying data, and the routed event & command prepared for message transmission.

The "data-driven interface" sounds a little abstract. Explanation in the vernacular (Chinese Vernacular seems to be not on the stage, and cannot be written in the book, but can be written in the vernacular) is-data is the bottom layer, is the heart, the data changes as the UI of the surface layer, and the data is displayed to the user. If the user modifies the value on the UI element, it is equivalent to directly modifying the underlying data through the UI element; the data is at the core, and the UI is subordinate. As a result, data is the engine (driver) of the program, and the UI becomes a "window" (driver) that almost does not contain any logic for users to observe data and modify data ).

By the way, if you are a winform programmer, "data-driven interface" will make you feel uncomfortable at first. For example, in winform programming, if you want to sort the items in ListBox, We will directly sort these items, that is, perform operations on the interface, this won't work in WPF. In fact, in WPF, because the interface is completely determined by data (or even the sorting of interface elements), we only need to sort the underlying data, as an interface, items also arranged the order in a data-driven manner.

So how is data transmitted from the underlying layer to the interface? Today's leading role, binding, is coming soon!


The Chinese name of binding is "very violent"-binding. I guess there is no standard for the earliest translators to follow. It probably uses homophonic sound! This homophonic voice does not matter. Chinese programmers may be confused. "Binding" refers to bundling, and adding a "fixed" character makes it feel like "binding together and holding it together. But actually? Binding is a loose coupling relationship between tunnels!

As shown in the following example, binding translated as "join" is not suitable. This entry exists in the English dictionary. Do you need to talk about association? Everyone knows that there is a relationship between them. Data Binding should no longer be called "Data Binding". It should be called "Data Association", which means that there are some relationships and linkages between data and interfaces (or other data.

In WPF, how is binding related and linkage? Just like our headlines -- binding is the "Green Channel" of data ". "Green Channel" represents "direct" and "fast", and binding is like this.

Let's share an interesting example. Please refer to the following:

Here is a UI composed of two textbox and a slider. The customer's requirement is: when the slider of the slider moves, the value of the slider is displayed in the textbox above; in turn, after you enter a proper value in the textbox above, move the mouse focus away And Slider's slider to the corresponding position.

From the perspective of a winform programmer, he will do the following:

  1. Responds to the valuechanged event of slider1 and enables textbox1 to display the value of slider1 In the event processing function.
  2. In response to the lostfocus event of textbox1, convert the text of textbox1 to a value and assign it to slider1.

Note! This is a typical idea of "non-data-driven interface. Why?

When we respond to the valuechanged event of slider1, we need the value of slider1. At this time, slider1 is at the core and is the "Source" of data ); when we respond to the lostfocus event of textbox1, what we need is its text attribute value. At this time, textbox1 becomes the source of data. That is to say, in this processing method, there is no fixed "Source" for the data. The two UI elements are equivalent and there is no problem of who belongs to whom. In other words, there is no "correlation" between them ".

Next, let's try the "Green Channel" shortcut!

The source code of the above example is as follows:

<Window x:Class="BindingSample.Window1"    xmlns=""    xmlns:x=""    Title="" Height="300" Width="300">    <Window.Background>        <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">            <GradientStop Color="Blue"  Offset="0.3"/>            <GradientStop Color="LightBlue" Offset="1"/>        </LinearGradientBrush>    </Window.Background>    <Grid>        <TextBox Height="23" Margin="10,10,9,0" Name="textBox1" VerticalAlignment="Top" />        <TextBox Height="23" Margin="10,41,9,0" Name="textBox2" VerticalAlignment="Top" />        <Slider Height="21" Margin="10,73,9,0" Name="slider1" VerticalAlignment="Top" Maximum="100" />    </Grid></Window>

After removing the hint in the flowers, the most important thing is only the following three lines (but in fact the textbox2 line of the 2nd line is just to let the mouse focus have a place ):

    <Grid>        <TextBox Height="23" Margin="10,10,9,0" Name="textBox1" VerticalAlignment="Top" />        <TextBox Height="23" Margin="10,41,9,0" Name="textBox2" VerticalAlignment="Top" />        <Slider Height="21" Margin="10,73,9,0" Name="slider1" VerticalAlignment="Top" Maximum="100" />    </Grid>


Then, I only need to make a small modification on the 1st line of code to complete the tasks that can be completed by using two event responses and more than 10 lines of code in winform:

    <Grid>        <TextBox Height="23" Margin="10,10,9,0" Name="textBox1" VerticalAlignment="Top" Text="{Binding ElementName=slider1, Path=Value}"/>        <TextBox Height="23" Margin="10,41,9,0" Name="textBox2" VerticalAlignment="Top" />        <Slider Height="21" Margin="10,73,9,0" Name="slider1" VerticalAlignment="Top" Maximum="100" />    </Grid>

After careful consideration, you will surely see one more sentence: text = "{binding elementname = slider1, Path = value }"

This sentence means: Hi, textbox1. Since then, your text attribute value is associated with the Value Attribute Value of the UI element slider1, when the value is changed, your text will also be changed.

At this time, the result is-you drag the slider, textbox1 will display the value (double precision, between 0 and 100); you enter a number between 0 and 100 in textbox1, when you move the mouse to textbox2, The slider1 slider will jump to the corresponding value,


It's very simple, isn't it? Please note that there is a "data-driven interface" model here! Here, we always regard the value of slider1 as a data source, while textbox1 is a window for displaying and modifying data (data presenter) -- slider1 is the core, the Value Attribute Value of textbox1 is changed. The text attribute value of textbox1 is also sent back to the value attribute value of slider1.

It's time for us to understand several key concepts of Data Binding --

  1. Data source: as the name suggests, it is the entity that maintains data, the source and source of data. It is up to the programmer to decide who to use as a data source-as long as you want to use it as the data core. It can be a UI element, an instance of a class, or a set (it is very important to bind a set, which is discussed in a specific article ).
  2. Path: a data source, as an entity, may have a lot of data. Which value do you pay attention? The value is path. In the above example, slider1 is source, which has a lot of data-Besides value, width, height, and so on, but it is not what we care about-so, we set path to value.
  3. Target: where will the data be transmitted? This is the data target. In the preceding example, textbox1 is the target of the data. Note that the target must be the receiver and driver of the data, but it is not necessarily the display of the data-maybe it is only a part of the Data Association-we will give an example later.
  4. Binding: the channel between the data source and the target. It is this channel that associates source with target to enable (directly or indirectly) the data to drive the interface!
  5. Set binding: specify a binding for the target and point the binding to an attribute of the target to complete "end-to-end" data transmission.

Level on the green channel ":

Now that the Olympics is approaching, security checks are also strengthened on all major traffic routes in Beijing. Microsoft also prepared several practical "checkpoints" for binding's "Green Channel ". The opening, closing, and setting of these "checkpoints" are completed by binding attributes. Common examples include:

  • If you want to limit the "Green Channel" to "one-way street", set the mode attribute of the binding instance, which is an enumeration value of the bindingmode type, it contains twoway, oneway, and onewaytosource values. In the above example, the default value is twoway, so there will be two-way data transmission.
  • If the user proposes that as long as the text of textbox1 changes the slider1 slider to respond immediately, set the updatesourcetrigger attribute of binding. It is an updatesourcetrigger type enumeration value. The default value is updatesourcetrigger. lostfocus, so the data will be updated when the mouse focus is removed. If you set it to updatesourcetrigger. propertychanged, so as long as the attribute associated with the target changes, it will be immediately sent back to source -- all we have to do is change a word, and winform programmers are facing a headache at this time, because he needs to move the code to another event response function.
  • What if the data types at both ends of the binding are inconsistent? It doesn't matter. You can set the converter attribute of binding. The specific content is discussed in the next article.
  • What if there are "inflammable and explosive" insecure factors in the data? OK. You can set the validationrules of the binding and add a group of "security check facilities" to it (also discussed in the next article ).

Set binding in C # code

The XAML code is so simple and simple. This is not something that can be done by C # programmers!

In an image, binding is like a box where some organs are installed to filter and control data. each end of the box is followed by a pipe, which is composed of a shell and a tube core, it looks like the following figure:


If you have such an image in your mind, follow these steps:

  1. Source: Determine which object is used as the data source
  2. Target: determines which object is used as the target.
  3. Binding: declares a binding instance.
  4. Connect a pipe to the source and insert the core into the source path.
  5. Connect the other pipe to the target and insert the tube core to the target linkage attribute.

If necessary, you can set the binding level between 3 and 4. In fact, the sequence after Step 1 is not fixed, but this step is easy to remember-all are connected to the right. The result looks like this:


I guess you might ask, "What is D. P ?"

D. p. the full name is "Dependency Property". The literal translation is "Dependency Property", which means that it itself has no value, its value is "dependent" on the attribute values of other objects, passed and converted by binding. As shown in the example, it is the linkage property driven by data on the target!

Here is the equivalent C # code. I wrote it in the constructor of window1:

Public window1 () {initializecomponent (); // 1. I plan to use slider1 as the source // 2. I plan to use textbox1 as targetbinding binding = new binding (); binding. source = This. slider1; binding. path = new propertypath ("value"); this. textbox1.setbinding (textbox. textproperty, binding );}

Interestingly, the operations on the source side, the receiver and the intubation core are divided into two steps, while the target side is completed in the setbinding method. Note that textbox. textproperty is a true Dependency Property! The dependency property document has been completed. I will select a yellow track and release it: P

The above code is slightly simplified, that is, to transfer the path settings to the binding structure:

Public window1 () {initializecomponent (); // 1. I plan to use slider1 as the source // 2. I plan to use textbox1 as targetbinding binding = new binding ("value"); binding. source = This. slider1; this. textbox1.setbinding (textbox. textproperty, binding );}

The advantage of this is that you can specify a source for the binding. As long as the source has the "value" attribute, the binding will automatically extract its value and transmit it to the target end.

We can also set some "levels" for binding ":

Public window1 () {initializecomponent (); // 1. I plan to use slider1 as the source // 2. I plan to use textbox1 as targetbinding binding = new binding ("value"); binding. source = This. slider1; binding. mode = bindingmode. twoway; binding. updatesourcetrigger = updatesourcetrigger. propertychanged; this. textbox1.setbinding (textbox. textproperty, binding );}

There is also a small prompt: if the source happens to be a UI element, you can also set the binding. source = This. slider1; rewrite to binding. elementname = "slider1"; or binding. elementname = This.;

Custom Data source:

In the daily work of our project team, we often need to write a class and use its instance as the data source. How can we make a Class A "qualified" data source?


  1. Defines some properties for this class, which is equivalent to providing the path for binding
  2. Enable this class to implement the inotifypropertychanged interface. The purpose of this interface is to notify the binding when the source attribute value changes (otherwise, how do people know that the source data has changed and the data is coordinated ?), So that the binding can transmit data to the target. In essence, the event mechanism is used, but it only masks the data at the underlying layer and does not require programmers to write event handler.

Let's write a class like this:

// Step 1: declare a class and prepare necessary attributes: public class student {private int ID; Public int ID {get {return ID;} set {id = value ;}} private string name; Public string name {get {return name;} set {name = value ;}} private int age; Public int age {get {return age ;} set {age = value ;}}}

The next step is to use the inotifypropertychanged interface to "arm" the class. Note that this interface is in the system. componentmodel namespace:

// Step 2: implement the inotifypropertychanged interface public class student: inotifypropertychanged {public event propertychangedeventhandler propertychanged; // This interface contains only one event private int ID; public int ID {get {return ID;} set {id = value; If (this. propertychanged! = NULL) {This. propertychanged. invoke (this, new propertychangedeventargs ("ID"); // notification that the value of binding is "ID" and the attribute value has changed.} private string name; public string name {get {return name;} set {name = value; If (this. propertychanged! = NULL) {This. propertychanged. invoke (this, new propertychangedeventargs ("name"); // notification that the value of binding is "name" has changed.} private int age; public int age {get {return age;} set {age = value;} // no notification is sent when the value of age is changed}
OK. Now, you can try to use the student class instance as the data source!

Custom Data target:

Don't give, don't give; don't give, don't give also -- "Salute-qu li"

Knowing how to define a data source, do you want to define another data target? Let's recall that binding is connected to the tube at the target end, and its core is inserted on a Dependency Property! So before we get familiar with Dependency Property, I am afraid we can only use the ready-made. Net object to act as the target!

Therefore, please pay attention to the subsequent articles on the WPF system!

========================================================== =

To put it bluntly:

  1. Urgent. NET development 3 ~ 3 persons with 5 years of experience, C ++ development 3 ~ 3 persons with 5 years of experience!
  2. In the future to help friends recruit. NET development/C ++ development/Java Development/software testing Junjie talent, interested parties please send your resume to the, or leave a message in my space. At the same time, I have many headhunting friends who are interested in my space and have many opportunities.
  3. In the future, you will be able to provide entry-level and preliminary training for. NET development in your spare time. For non-profit organizations and community organizations related to students' learning and employment, I will provide free training services.
  4. Repost this article. Please repost the above ads together. Thank you!




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: 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.