WPF Principle Analysis-dependency attributes and additional attributes

Source: Internet
Author: User

I. common attributes

First, let's discuss the attributes in. net. When we write a class, we need to define some fields to save some values.

public class Person{   public string nam;   public int age;}

However, we will find that such a definition cannot meet our needs. For example, we need to implement some restrictions on field verification. At this time, we need to implement attributes for us. Because we can write our verification logic when setting attributes.

public class Person{   private string name;   private int age;   public int Age   {     get{return age;}     set{      if(value>100&&value<0)        age=100;       else        age=value;      }   }}

The following describes the principles of common attributes. The common attribute is only a sugar coat of the field. It cannot save the value itself. After vs is compiled, it will be compiled into the corresponding method (because methods, whether static or non-static, will only have one copy in the memory, so even if we create multiple instances, our memory will not increase ).

Ii. Dependency attributes

Dependency attribute is a special property in WPF and an upgraded version of common attributes. Because its value depends on other objects, it can have no value itself, which can greatly save the memory overhead of the instance. Think about the fact that every element in WPF has dozens of attributes. If we need to initialize the attributes when creating each element, and assign values to the attributes, in this way, the memory of our system will be greatly increased.

In WPF, objects can be created without the space used to store data (that is, the space occupied by fields ), only retain the ability to obtain default values, borrow data from other objects, or allocate space in real time when data is needed. This type of object is called a dependency object) the ability to obtain data in real time depends on the Dependency Property. -- Go deep into WPF

 1. create dependency attributes

 public class Student : DependencyObject    {       public static readonly DependencyProperty NameProperty = DependencyProperty.Register("Name", typeof(string), typeof(Student));    }

A. the class to which the dependency property belongs must inherit the dependencyobject class,
B. Default public static readonly,
C. The name of the Dependency Property should end with property,
D. Use the dependencyproperty. Register static method for registration.
E. Three parameters of the Register Method (1. Name of the Dependency Property package, 2. Retention Value Type of the Dependency Property, and 3. Host type of the Dependency Property)

In fact, we have created a simple dependency attribute so that we can use it.

Student Stu = new student (); // assign Stu to the dependency attribute through setvalue of the dependencyobject class. setvalue (nameproperty, tb1.text); // get the dependency attribute value tb2.text = Stu through the getvalue of the dependencyobject class. getvalue (nameproperty ). tostring ();

The setvalue of dependencyobject is used to assign values to the dependency attribute. getvalue is used to obtain the value of the dependency attribute. Here we will find that the dependency attribute can save the value, and the common attribute we mentioned above (its value is still saved in the field ).
2. Add a property package

In WPF, we use an attribute package to wrap our dependency attributes for ease of use.

        public string Name        {            get { return (string)GetValue(NameProperty); }            set { SetValue(NameProperty, value); }        }

In this way, our dependency attributes are exposed to the outside world through an attribute package, so that we can use the dependency attributes when using common attributes.
3. Forced callback and verification callback
In WPF, we can directly assign values to the dependency attribute through setvalue. In this way, we cannot perform related verification when assigning values to the dependency attribute like the preceding common attribute, however, WPF provides two delegates for us to verify callback and force callback.
Validatevaluecallback: This callback function can accept or reject new values. It provides a callback function as a dependency. Register () parameter. This function must point to only one method that accepts an object parameter and returns a Boolean value. If the return value is true, the request is accepted. If the return value is false, the request is not accepted.
Coercevaluecallback: This callback function can change a new value to a more acceptable value. This callback is generally used to deal with conflicting dependency attribute values set for the same object (for example, when setting the value of maximum, minimum, and value of scrollbar .)

View code

Propertymetadata metadata = new propertymetadata (); // force callback when setting the maximum age, because the maximum age must be greater than the minimum age private static object coercemaxage (dependencyobject D, object value) // There are two parameters: the object to be applied to the value and the value to be used {student Stu = D as student; If (INT) value <Stu. minage) return Stu. minage; else return value;} // force callback when you set the age, because the value of this parameter must be private static object coerceage (dependencyobject D, object Value) between the maximum age and the minimum age) {student Stu = D as student; If (INT) value> Stu. maxage) return Stu. maxage; else if (INT) value <Stu. minage) return Stu. minage; else return value;} // verification callback. If the set value does not meet the requirements, an exception Private Static bool israngeable (object Value) {int I = convert will be thrown. toint32 (value); if (I> = 0 & I <150) return true; else return false;} public static readonly dependencyproperty ageproperty = dependencyproperty. register ("Age", typeof (INT), typeof (student), new propertymetadata () {defaultvalue = 0, coercevaluecallback = new coercevaluecallback (coerceage)}, new validatevaluecallback (student. israngeable); Public int age {get {return (INT) getvalue (ageproperty);} set {setvalue (ageproperty, value );}} public int maxage {get {return (INT) getvalue (maxageproperty);} set {setvalue (maxageproperty, value) ;}} public static readonly dependencyproperty maxageproperty = dependencyproperty. register ("maxage", typeof (INT), typeof (student), new propertymetadata (0) {metadata = new coercevaluecallback (coercemaxage), propertychangedcallback = new propertychangedcallback (D, E) => {student Stu = D as student; Stu. coercevalue (student. ageproperty) ;}); Public int minage {get {return (INT) getvalue (minageproperty) ;}set {setvalue (minageproperty, value );}} public static readonly dependencyproperty minageproperty = dependencyproperty. register ("minage", typeof (INT), typeof (student), new propertymetadata (New propertychangedcallback (d, e) =>{ student Stu = D as student; // when the minimum age value changes, force the callback of the maximum age value Stu. coercevalue (student. maxageproperty); Stu. coercevalue (student. ageproperty );})));

In this Code, I simulated a scrollbar to set three values: set the maximum and minimum values of age and age.
I used a verification callback when setting the age, so that an exception occurs when we enter an invalid age. Forced callback is used when the maximum age is set, because this ensures that the maximum age is greater than or equal to the minimum age, and I also use force callback when setting the age, this ensures that the age is between the maximum and minimum values.

The book says that the Force callback will be executed before the verification callback, But when I debug it, I find that the result is the opposite and I don't know why.

When assigning values to dependency properties, the event execution sequence is coercevaluecallback -- validatevaluecallback -- propertychangedcallback.

3. Additional attributes
An additional property means that an attribute does not belong to a certain object, but is subsequently attached to it due to a certain requirement. For example, we use grid. Row and canvas. Left for element layout. Its registration and usage are almost the same as the dependency attributes.

 

 

 

 

 

 

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.