On the binding expression of WPF

Source: Internet
Author: User
Whether you define a control or a user control, you will use a function-binding. The written term: element binding. This means that the bound element implements data synchronization. In my opinion, the introduction of WPF into this feature is really perfect. Programming is more specific. Especially with the MVVM pattern, it's called perfection. The author is not an academic school. It is unrealistic to tell the story in a comprehensive way. From the author's use of experience to talk about binding it.

The most common way to use his target element is the DataContext object on the control. As follows:

<textblock grid.column= "0" text= "{Binding dishname}" style= "{StaticResource takingdishdishnametextstyle}"/>

DataContext This attribute is above the FrameworkElement class. This means that most of the controls will have their own datacontext. Then we generally only set the DataContext property on the outermost layer. For a clearer understanding of DataContext bindings. The author makes a simple example. The author sets the DataContext value for the outermost window. It also sets the DataContext value for his internal grid. But they're not the same. The object type is just the same as the property. As follows

<window x:class= "Wpf.mainwindow" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:aomi= "Http://aomiwpf.com/ModernUI" xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "Clr-namespace: WPF "title=" MainWindow "height=" width= "525" ><window.datacontext><local:winddatacontext/></ Window.datacontext><grid><grid.datacontext><local:griddatacontext/></Grid.DataContext ><textblock text= "{Binding  testname}" ></TextBlock></Grid></Window>

Execution Result:

Experiments can prove that the target element of the standard binding method is DataContext. He'll find the closest DataContext to the current binding element. We're coming up with a hypothesis--what if the attribute testname in the Griddatacontext class is replaced with TestName1? As follows

1 public class Griddatacontext:notifypropertychanged 2     {3         private string _testname1 = "Griddatacontext"; 4  5 Public         String TestName1 6         {7             set 8             {9                 if (this._testname1! = value) One                 {                     this._ testName1 = value;13                     onpropertychanged ("TestName1");                 }15             }16             get {return this._testname1;}         }18     }

Execution Result:

Excuse me! I thought he would go to the DataContext property of window testname. Obviously he won't. It also shows that he will only go to the close DataContext inside to find. Not a straight one to look up.

It is important to note that if the above only writes {binding}, it is to bind the current DataContext. Instead of his attributes.

In the development process, we often want an element to be bound to a property above another element. As soon as another element's property changes, an element is notified to change. This is the time to have to use the following way.

{Binding elementname=somethingname, path=text}

ElementName: Represents the name of the element.

Path: Represents the properties of an element object.

In fact, we can think of a problem. The binding is not only one party affects one side. This is the pattern to be used in the binding. As follows

{Binding elementname=somethindname, path=text,mode=twoway}

TwoWay: Causes changes to the source or target properties to automatically update each other.

OneWay: Updates the binding target (target) property when the binding source (source) changes.

OneTime: Updates the binding target when the application starts or when the data context changes.

OneWayToSource: Updates the Source property when the target property changes.

The above usage is more commonly used. is also relatively simple. Let's look at a binding expression inside an open source project. As follows

<button command= "{Binding source={x:static Systemcommands.minimizewindowcommand}}" tooltip= "{x:Static Modernui: Resources.minimize} "style=" {StaticResource Systembutton} ">   <Button.Content>  <grid width=" 13 " height= "rendertransform=" 1,0,0,1,0,1 "> <path data=" m0,6 l8,6 Z "width=" 8 "height=" 7 "verticalalignment=" Center "horizontalalignment=" center "  stroke=" {Binding Foreground, Relativesource={relativesource mode= FindAncestor, Ancestortype=button}} "strokethickness=" 2 "  />  </Grid>  </Button.Content> </Button>

I don't know if we can see it clearly. The above means that the foreground from the parent node button and the stroke of the current path are bound together. The main key is in Ancestortype. The type used to specify the father. Mode is a relativesourcemode type. He has a value of four. As follows.

Previousdata: Used for data lists, meaning previous data items. That is the display above the data collection. Controls are not included.

TemplatedParent: Used for bindings on templates.

Self: The attribute on the element itself is bound.

FindAncestor: Used to find the parent element.

As long as this is explained, you can understand that RelativeSource is used to specify relative source elements. That is the target element.

In fact, the above expression has a possible notation. That is, one more depth to limit the parent (ancestorlevel). As follows

{Binding Relativesource={relativesource FindAncestor, Ancestortype={x:type ItemsControl}, ancestorlevel=2}, Path= Name}

Note: If you want to modify the value of the binding, use the converter. As follows

{Binding elementname=somethindname, path=text,mode=twoway,converter=xxxconverter}

When developing a custom control, we often use an expression. As follows

  Width= "{TemplateBinding Width}"

The above notation is just an abbreviation. Complete the following

Width= "{Binding relativesource={relativesource templatedparent}, Path=width}"

It can be said that the above content is the most commonly used by the author. Next, let's look at some of the other content points that bind. That is the less common content.

1.StringFormat function. Equivalent to the String.Format function. Give me an example. If we want to add "¥" before the amount, we can use it. As follows

<textblock text= "{Binding moneytext, stringformat=¥{0}}"/>

If you do not do this, you will have to give the "¥" a TextBlock to show, or moneytext into a string type, and then set the value inside with ¥. But the author here is a double type. So with the function of StringFormat can be perfect to solve the problem of displaying "¥".

Execution Result:

The function of 2.TargetNullValue is used to bind the content to be displayed when the target is a null value. The following author assigns null to Nullname.

<textblock text= "{Binding nullname, Targetnullvalue=aomi}"/>

Execution Result:

The 3.FallbackValue feature is used to bind the target to what is to be displayed when an error occurs. As follows

<textblock text= "{Binding nullname, Fallbackvalue=aomi}"/>

The results of the implementation of the author will not post.

article at the end. In order to illustrate a infrequently used function--prioritybinding. The author of this function is not good to say. You can only let the reader understand it by themselves. He is mainly used for information to be displayed when loading time is much higher. For example, "Loading ..." is displayed. I made an example of it.

Xaml:

<window x:class= "Wpf.mainwindow" xmlns= "http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:aomi= "Http://aomiwpf.com/ModernUI" xmlns:x= "http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local = "Clr-namespace: WPF "title=" MainWindow "height=" width= "525" ><window.datacontext><local:mainviewmodel/></ Window.datacontext><grid><textblock><textblock.text><prioritybinding><binding Path= "UserName" isasync= "True" ></binding><binding path= "Loadingname" ></binding></ Prioritybinding></textblock.text></textblock></grid></window>

ViewModel:

public class mainviewmodel:notifypropertychanged    {private String _username = "Haya";p rivate string _loadingname = "positive In load ... ";p ublic string UserName        {set{if (this._username! = value)                {this._username = value;                    OnPropertyChanged ("UserName");                }            } get {                thread.sleep (7000); return this._username;            }        } public string Loadingname        {set{if (this._loadingname! = value)                {this._loadingname = value;                    OnPropertyChanged ("Loadingname");                }            } get {return this._loadingname;}        }    }

Execution Result:

After seven seconds:

The content of this chapter is relatively simple. The author just tells some common knowledge points. But that's not what it's all about. For example, binding also relates to XML bindings and the binding capabilities of the collection. Readers can look for information on their own.

Related Article

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.