Preface: This is still some text that has not been strictly reviewed. Although I did execute the first draft, redraft, and review to ensureArticleQuality method, but still worried about whether there is any error. I hope you can help me to point out that the next time I update the version, I will correct it. All errors, including non-words, unclear concepts (incorrect expressions, etc.), and marginal situations are not covered. In your opinion, all aspects that need to be mentioned can be discussed in depth.
In the previous process of Binding data sources, this article used the source attribute of the binding class to specify the data source. Using this property to access the binding source has some limitations: software developers cannot reference elements defined in XAML or find elements related to the binding source according to certain rules. Therefore, besides the source attribute, WPF also provides methods such as elementname and relativesource to help you specify the binding source.
Elementname is used to reference (or even back-to-reference) an interface with a name explicitly specified in the same nametypex. The binding will look up along the element where it is located along the logic tree until the first element with a namelist is encountered and the name is searched in the namelist. (Not accurate, but it will be the majority of cases you are exposed)
The elementname attribute and the source attribute are mutually exclusive, that is, when both attributes are set,ProgramWill throw an exception at runtime. After the interface element to be specified is correctly referenced, the binding source currently bound will be the interface element, and the attribute to be bound is specified by the path attribute.
Relativesource is used to specify the binding source related to the current interface element. There are several ways to use it for search. When searching for itself, use the Self Mode:
1{Binding relativesource = {relativesource self }}
The findancestor mode is used to find the specific type of the ancestor:
1{Binding Path = actualwidth, relativesource = {relativesource mode = findancestor, ancestortype = scrollcontentpresenter }}
When binding an Application Template's data items, use the templatedparent mode:
1{Binding relativesource = {relativesource mode = templatedparent }}
The previusdata mode is used when you bind data to a data item before the current item in the data item set. There are few examples of using previusdata binding on the network, so here, I will provide a complete example:
1 < Window ...
2 Xmlns: Local = "CLR-namespace: binding_previusdata"
3 X: Name = "Mainwindow" >
4 < Window. Resources >
5 < Local: historyconverter X: Key = "Historyconverter" />
6
7 < Datatemplate X: Key = "Historytemplate" >
8 < Textblock >
9 < Textblock. Text >
10 < Multibinding Converter =" {Staticresource historyconverter} " >
11 < Binding Relativesource =" {Relativesource previusdata} " />
12 < Binding />
13 </ Multibinding >
14 </ Textblock. Text >
15 </ Textblock >
16 </ Datatemplate >
17 </ Window. Resources >
18 < Stackpanel >
19 < Dockpanel >
20 < Button Dockpanel. Dock = "Right" Content = "Submit" Click = "Onbuttonclicked" />
21 < Textbox X: Name = "Minput" />
22 </ Dockpanel >
23 < ListBox Itemtemplate =" {Staticresource historytemplate} " Itemssource =" {Binding elementname = mainwindow, Path = history} " />
24 </ Stackpanel >
25 </ Window >
1 Public Partial ClassWindow1: Window
2{
3...
4PublicObservablecollection <String> History...
5}
The methods for binding source are complementary to each other through the source, elementname, relativesource, and other attributes. Generally, source is used to reference data in the data layer. elementname refers to the composition of the UI logic tree, while relativesource is often used to find the binding source from the visual tree, you can even traverse the root element of the current XAML file. Therefore, when deciding to bind the source, the software developer needs to decide the method to use based on the actual search method.
In binding, it is not enough to specify the bound source. Please consider specifying various methods to bind the Source: elementname is used to reference the elements given in the logic tree; relativesource is used to specify other elements associated with the current element; and source is more common, it only accepts various expressions, such as staticresource, which are often used to reference instances of a specific nature. The binding operations are often the attributes of these sources, or even subattributes. Software developers need to specify the attributes of the binding source involved in the binding. This is also the reason why the binding provides the path attribute and the XPath attribute.
Generally, all attributes specified by the bound path must provide support for property change notifications. At least software developers should be able to ensure that the property change notification can be sent in a timely manner when binding is required. For example, in the implementation of the inotifypropertychanged interface, software developers need to explicitly send the propertychanged event. As far as dependencyproperty is concerned, the transmission of change notifications is handled by the WPF property system. In addition, the bound path attribute provides support for structured data. For example, for point-type attribute location, software developers can set path to location. X. The advantage of doing so is that providing support for structured data can have better semantic features. Another advantage is that updating the structured data can avoid the order of each attribute in it when updating, so that many bindings dependent on the data can execute the binding logic in the error state.
Another common concern is the binding update. If the path specified in the binding is x.y and X sends a message about y change, then whether the binding will be executed. The answer is yes.
If the bound source is XML data rather than CLR objects, software developers need to use the XPath attribute to specify the binding source to be used, rather than the path.
After explaining the bound data source, please take a look at the bound target. WPF requires that the bound target attribute must be a dependency attribute, rather than a field or other components. You may wonder why the bound target attribute must be a dependency attribute? The reason is simple: in addition to the support for binding, changes to dependency attributes may also lead to changes in layout and other functions. For example, the text attribute of textblock may increase the space required by textblock. At this time, attribute changes should not only participate in binding function execution, but also participate in layout systems, rendering systems, and other WPF subsystems in a very efficient manner. The efficient way to participate in each subsystem is the dependency attribute.
Generally, bindings are used in XAML, so the use of binding targets is often a matter of course: the bound target attribute is often dependencyproperty, the bound property is in the dependencyobject instance.
If only the association between the source attribute and the Target attribute is provided, the binding function may not be that great. Consider the following situation: If a software developer wants to bind the source property to the text property of Textbox, the source property will no longer match the target property when the user changes the text displayed in textbox. There are many such examples, and the solution provided by WPF is the mode attribute bound. There are four main modes: twoway, oneway, onewaytosource, and onetime. The twoway mode provides the most powerful functions. Once the attribute involved in binding changes in the binding source or the bound target attribute changes, the binding will be executed. In this mode, the binding will not only pass the changes of the bound source attribute to the target attribute, but also pass the changes to the source attribute when the target attribute changes. This type of binding is often used when the binding target attribute can be changed from the user interface, such as the text attribute of textbox. The other one-way mode is the most common binding mode. If the attribute involved in binding in the binding source is a read-only attribute, or the bound target attribute is not changed due to other external factors, oneway binding is the best choice for binding. Similar to the oneway mode, the onewaytosource mode is used. This mode can be used to bypass binding restrictions on target attributes: Binding requires that the target attribute must be dependencyproperty. In some cases, software developers need a property that is not dependencyproperty and changes according to the change of a dependencyproperty property. Finally, as shown in its name, the onetime mode only runs once.
In terms of performance, the oneway binding overhead is smaller than the twoway binding overhead. Onetime is a more lightweight binding mode than oneway mode.
A knowledge point related to the binding mode is: when creating a dependencyproperty as the binding source, the bindstwowaybydefault attribute in the metadata of the dependency attribute is used to control whether a dependency attribute is bound in two-way by default.
Next, bind an update notification. The binding provides two additional events: sourceupdated and targetupdated. To activate these two additional events, the software developer needs to set the corresponding property notifyonsource (target) updated to true. With this additional event, software developers can interact with other interface elements to extend the flexibility of binding execution logic. In addition, an attribute update is often related to its update mode. Software developers can use the updatesourcetrigger attribute to determine the cause of trigger source update, such as the textbox update condition.
In addition, the binding in WPF also has another mode: asynchronous mode. The attribute related to this mode is isasync. When the value of this attribute is set to true, binding will take a thread from the thread pool to process the binding, so as to avoid blocking the UI when binding the evaluate value. When the attribute access character is not returned, the binding will temporarily use fallbackvalue as the bound value. If fallbackvalue is not set, the binding result is the default value of the bound target attribute. This binding mode is useful when the source attribute value takes a long time to obtain.
Xmldataprovider. isasynchronous and objectdataprovider. isasynchronous attributes also provide this function.
Another important concept related to binding is the master-slave mode: if the property is selector in the bound instance. if issynchronizedwithcurrentitem is set to true, the currently selected item synchronizes the currentitem attribute of the collectionview associated with it. If other data of the set type is not accepted, only the attributes of a single data can be directly bound to the attributes of the set data item. In fact, they are bound to the currentitem attribute associated with the collectionview.
Another problem is: What should I do when the bound target is inconsistent with the attribute in the bound source? In fact, this is the function provided by the bound converter. After the converter attribute is used to indicate the converter used for binding, the converter is called for each operation of the binding to convert the value of the source attribute to the value of the required Target attribute. When using the converter, software developers can also use the converterparameter attribute to indicate parameters for the converter to allow the converter to use this parameter during conversion of the Target attribute.
Implementing a bound converter is very simple: Software Developers only need to implement ivalueconverter or imultivalueconverter:
1 Internal Class Inttovisibilityconverter: ivalueconverter
2 {
3 Public Object convert ( Object Value, type typetarget, Object Param, cultureinfo Culture)
4 {
5 Return ( Int ) Value = 0 ? Visibility. collapsed: visibility. visible;
6 }
7
8 Public Object convertback ( Object Value, type typetarget, Object Param, cultureinfo Culture)
9 {
10 Throw New Notsupportedexception ();
11 }
12 }
When implementing a converter, software developers are advised to use the valueconversion feature to modify this implementation to indicate the data types involved in the conversion to development tools.
Since imultivalueconverter is mentioned, you have to mention another binding: multibinding. The binding takes multiple bindings as sub-elements and is executed after the source of each sub-binding changes. The conversion logic implemented by imultivalueconverter is used to convert the source data to the values required for the target attribute. It is precisely because the multibinding will be executed when the binding changes. Software developers have to consider some special cases when using multibinding. A serious case is the multibinding of two correlated data. When one of the data changes, multibinding is executed to reflect data updates. However, the other data associated with the data is not in the correct State, resulting in incorrect results. More seriously, the program crashes. The substring is not suitable for multibinding. If multibinding is used to input the string to be operated and the starting position of the substring, another data may be invalid when any data source changes, such as when the string changes, the starting position of the substring may be greater than the length of the string. The solution to this problem is to provide a structured data for the associated information and use it as the bound source attribute. Each time a string changes, the software developer creates a new structured data and correctly records the string and its starting position. When the structured data is updated, the data recorded inside the data is unified to ensure the correct execution of the binding.
Another point to be mentioned is the inheritance of the attributes of the multibinding class by the subbinding. The value of the mode attribute and updatesourcetrigger attribute of the multibinding class will be inherited by each of its sub-bindings, unless the sub-bindings in the class override this attribute.
Multibinding currently only supports binding objects, but does not support multibinding or prioritybinding objects. This is because converter itself supports the simulation of these two types of objects.
In addition to multibinding, another special binding is prioritybinding. It also accepts a group of binding as sub-elements, and assigns priority to these sub-bindings in turn from high to low. At runtime, prioritybinding returns the value of the binding with the highest priority for successful execution. The value marked by fallbackvalue will be used if all bindings are not successfully executed or returned. In general, this binding is used to handle situations where it takes a long time for the source attribute to be bound to successfully return the result. It is similar to the asynchronous mode binding. However, the difference is that the fallbackvalue marked by the asynchronous mode binding can only be indicated in the XAML. If the software developer wants the fallbackvalue to change according to the data layer status, he needs to select prioritybinding, and assign the prioritybinding a binding with the lowest priority. At the same time, the binding with the lowest priority is often a synchronous binding, which is used as fallbackvalue in prioritybinding. Second, asynchronous mode binding does not support multiple bindings. When you need to perform a large number of time-consuming operations but want to give the user a rough calculation result, using multiple bindings in prioritybinding and executing these two computations at the same time is often a more appropriate solution. Finally, the asynchronous feature provided by prioritybinding is actually provided by the asynchronous feature of each sub-binding.
To sum up, this running mode of prioritybinding determines the running mode of each sub-binding: Except for the last sub-binding, the isasync attribute of each other binding needs to be set to true, these time-consuming functions are executed asynchronously, and the running results of prioritybinding are updated as appropriate after completion. For the last sub-binding, setting isasync to true is no longer a mandatory requirement. If the isasync attribute is not set to true, the last binding will be used as a more flexible fallbackvalue. If the isasync attribute is not set to true, all bindings are executed asynchronously, and the data initially displayed in the binding is the data specified by fallbackvalue of prioritybinding.
In addition, the fallbackvalue for each asynchronous sub-binding in prioritybinding will affect the execution of prioritybinding. If you are interested, you can test it on your own. In terms of personal experience, software developers should not set the fallbackvalue of asynchronous sub-binding.
Now, you may have a question in your mind: It seems that when a suitable converter is provided, multibinding can also achieve the effect of prioritybinding. I think my answer to this question is yes. The following is a simple implementation I have provided for this problem:
1 < Window ...
2 Xmlns: Local = "CLR-namespace: simulatedprioritybinding" >
3 < Window. Resources >
4 < Local: prioritizedconverter X: Key = "Prioritizedconverter" />
5 </ Window. Resources >
6 ......
7 < Multibinding Converter =" {Staticresource prioritizedconverter} " >
8 < Binding ... Path = "Moreslowproperty" Isasync = "True" />
9 < Binding ... Path = "Slowproperty" Isasync = "True" />
10 < Binding ... Path = "Quickproperty" />
11 </ Multibinding >
12 </ Window >
1 Public Class Prioritizedconverter: imultivalueconverter
2 {
3 Public Object Convert ( Object [] Values, type targettype, Object Parameter, cultureinfo Culture)
4 {
5 Foreach ( Object Value In Values)
6 If (Value! = Dependencyproperty. unsetvalue)
7 Return Value;
8 Return Dependencyproperty. unsetvalue;
9 }
10
11 Public Object [] Convertback...
12 }
In fact, this feature overlaps, and even prioritybinding only provides a subset of the features provided by multibinding. This row is not surprising. WPF often provides simplified versions for some common syntax structures and may improve performance, such as the binding of templatebinding in the templatedparent mode. This is slightly different from the strict features of the C # Language (that is, the design principles of the first few versions of C # are as follows: One thing, try not to provide two methods. For example, a static member function can only be called by type, while C ++ can be called by type and type instance ).
Another special type of binding is templatebinding. In fact, it is similar to the binding using templatedparent, but it has fewer functions than the binding, and is more efficient because of its lighter size. This is because in the templatebindingexpression class, the implementation of getvalue only obtains the value of a specific attribute, rather than tedious calculation. Since it is bound to a data instance using the template, this class only provides the property to specify the property to be bound.
(To be continued)
Source code download: http://download.csdn.net/detail/silverfox715/3907934
Reprinted please indicate the original address: http://www.cnblogs.com/loveis715/archive/2011/12/15/2288272.html
Business reprint please contact me in advance: silverfox715@sina.com