C # general type converter

Source: Internet
Author: User

C # general type converter

Introduction

In a recent project, some custom attributes must be edited through propertygrid during design and runtime, for example, the pop-up form editing, drop-down box editing, and attribute expanding editing methods are displayed. view the property editing of some controls of.
Also, the conversion between custom types and strings (similar to int. parse and Int. tryparse) is also frequently used and implemented.

Technical preparation
To address the first problem, we all know that when designing the attribute, Vs will automatically call the type converter and Type Editor set for these types of definitions, such as typeconverterattribute and editorattribute.
For the second problem, it is relatively simple to implement a typeconverter of the custom type.
Since all types I need to edit are custom types and there is a certain degree of nesting relationship, all of them need to achieve the corresponding effect, you must implement "type converter" and "Type Editor" of all my custom types ". The "all" custom type knows the workload when you think of it. At the beginning, I also patiently implemented several typeconverter custom types (I believe that for specific types of converters, everyone has their own two brushes, no nonsense ). However, there are still many custom types that I can't bear.
Based on previous experiences in implementing typeconverter, we have found many commonalities between these "Type converters. With this in mind, I decided to implement a "general type converter" and put most of the work to it.

Start
In. net or C ++, to achieve "universality", the first thing you think of is the generic type. Good, implementation is nothing more than using the following technologies: generic, reflection.
The "general-purpose type converter" is now published, and there may be some omissions. Please give us more advice.
//////////////////////////////////////// /// // <Br/> // copyright (c) 2009 keepsoft <br/> // All Rights Reserved <br/> /// <br/> // file: typeconvertergeneral. CS <br/> // Author: tianfj <br/> // createdate: 0:25:15 <br/> // description: implement the generic type converter edited by the Type attribute <br/> //////////////////// //////////////////////////////////////// /<br/> using system; <br/> using system. collection S; <br/> using system. collections. generic; <br/> using system. text; <br/> using system. componentmodel; <br/> using system. componentmodel. design. serialization; <br/> using system. globalization; <br/> using system. reflection; </P> <p> namespace skinsharpbuilder <br/>{< br/> /// <summary> <br/> // implement the generic type converter edited by the Type attribute <br/> // note: when using this function, you must first inherit a type converter from this generic type converter, generic T should be the target type of the type converter <br/> /// </Summary> <br/> // /<Typeparam name = "T"> </typeparam> <br/> public class typeconvertergeneral <t>: typeconverter where T: New () <br/>{< br/> Public override bool canconvertfrom (itypedescriptorcontext context, type sourcetype) <br/>{< br/> return (sourcetype = typeof (string )) | base. canconvertfrom (context, sourcetype); <br/>}</P> <p> Public override object convertfrom (itypedescriptorcontext context, cultureinf O Culture, object Value) <br/>{< br/> // string is similar to: classname {A = A, B = B, C = C} <br/> string strvalue = value as string; <br/> If (strvalue = NULL) <br/>{< br/> return base. convertfrom (context, culture, value); <br/>}< br/> strvalue = strvalue. trim (); <br/> If (strvalue. length = 0) <br/>{< br/> return NULL; <br/>}< br/> If (Culture = NULL) <br/>{< br/> Culture = cultureinfo. currentculture; <br/ >}< Br/> // char sepchar = culture. textinfo. listseparator [0]; <br/> char sepchar = '|'; </P> <p> type = typeof (t ); <br/> // 1. Remove "classname {" and "}". <br/> string withstart = type. name + "{"; <br/> string withend = "}"; <br/> If (strvalue. startswith (withstart) & strvalue. endswith (withend) <br/>{< br/> strvalue = strvalue. substring (withstart. length, strvalue. length-withstart. length-wit HEND. length); <br/>}< br/> // 2. Split the attribute value <br/> string [] strarray = strvalue. split (New char [] {sepchar}); <br/> // 3. Create an attribute set table <br/> hashtable properties = new hashtable (); <br/> for (INT I = 0; I <strarray. length; I ++) <br/>{< br/> string STR = strarray [I]. trim (); <br/> int Index = Str. indexof ('='); <br/> If (index! =-1) <br/>{< br/> string propname = Str. substring (0, index); <br/> string propvalue = Str. substring (index + 1, str. length-index-1); <br/> propertyinfo Pi = type. getproperty (propname); <br/> If (Pi! = NULL) <br/>{< br/> // type converter corresponding to this attribute <br/> typeconverter converter = typedescriptor. getconverter (Pi. propertytype); <br/> properties. add (propname, converter. convertfromstring (propvalue); <br/>}< br/> return this. createinstance (context, properties); <br/>}< br/> Public override bool canconvertings (itypedescriptorcontext context, type destinationtype) <br/>{< br/> return (destinati ONTYPE = typeof (instancedescriptor) | base. canconvertion (context, destinationtype); <br/>}< br/> Public override object convertion (itypedescriptorcontext context, cultureinfo culture, object value, type destinationtype) <br/>{< br/> If (destinationtype = NULL) <br/>{< br/> throw new argumentnullexception ("destinationtype "); <br/>}< br/> If (value is t) <br/>{< br/> If (destinationtype = T Ypeof (string) <br/>{< br/> If (Culture = NULL) <br/>{< br/> Culture = cultureinfo. currentculture; <br/>}< br/> // string separator = culture. textinfo. listseparator + ""; <br/> string separator = "|"; <br/> stringbuilder sb = new stringbuilder (); <br/> type = value. getType (); <br/> Sb. append (type. name + "{"); <br/> propertyinfo [] Pis = type. getproperties (bindingflags. instance | bindin Gflags. Public); <br/> for (INT I = 0; I <PIs. length; I ++) <br/>{< br/> If (! Pis [I]. canread) continue; </P> <p> type typeprop = Pis [I]. propertytype; <br/> string nameprop = Pis [I]. name; <br/> Object valueprop = Pis [I]. getvalue (value, null); </P> <p> typeconverter converter = typedescriptor. getconverter (typeprop); </P> <p> Sb. appendformat ("{0 }={ 1}" + separator, nameprop, converter. converttostring (context, valueprop); <br/>}< br/> string strcontent = sb. tostring (); <br/> If (STRC Ontent. endswith (separator) <br/> strcontent = strcontent. substring (0, strcontent. length-separator. length); <br/> strcontent + = "}"; <br/> return strcontent; <br/>}< br/> If (destinationtype = typeof (instancedescriptor )) <br/>{< br/> constructorinfo constructor = typeof (t ). getconstructor (New Type [0]); <br/> If (constructor! = NULL) <br/>{< br/> return New instancedescriptor (constructor, new object [0], false ); <br/>}< br/> return base. convertize (context, culture, value, destinationtype); <br/>}</P> <p> Public override object createinstance (itypedescriptorcontext context, idictionary propertyvalues) <br/>{< br/> If (propertyvalues = NULL) <br/>{< br/> throw new argumentnullexception ("propertyvalues "); <Br/>}< br/> type = typeof (t); <br/> constructorinfo CI = type. getconstructor (New Type [0]); <br/> If (CI = NULL) return NULL; <br/> // call the default constructor to construct an instance <br/> Object OBJ = CI. invoke (new object [0]); <br/> // set properties <br/> propertyinfo [] Pis = type. getproperties (bindingflags. public | bindingflags. nonpublic | bindingflags. instance); <br/> Object propvalue = NULL; <br/> for (INT I = 0; I <Pis. length; I ++) <br/>{< br/> If (! Pis [I]. canwrite) continue; <br/> propvalue = propertyvalues [Pis [I]. Name]; <br/> If (propvalue! = NULL) <br/> Pis [I]. setvalue (OBJ, propvalue, null); <br/>}< br/> return OBJ; <br/>}</P> <p> Public override bool getcreateinstancesupported (itypedescriptorcontext context) <br/>{< br/> return true; // return whether to call the createinstance method to create a new value to change the value of this object. <Br/>}</P> <p> Public override propertydescriptorcollection getproperties (itypedescriptorcontext context, object value, attribute [] attributes) <br/>{< br/> // The attribute is displayed in the declared order of the type. <br/> type = value. getType (); <br/> propertyinfo [] Pis = type. getproperties (bindingflags. instance | bindingflags. public); <br/> string [] names = new string [Pis. length]; <br/> for (INT I = 0; I <names. length; I ++) <br/>{< br/> Names [I] = Pis [I]. name; <br/>}< br/> return typedescriptor. getproperties (typeof (t), attributes ). sort (names); <br/>}</P> <p> Public override bool getpropertiessupported (itypedescriptorcontext context) <br/>{< br/> return true; <br/>}</P> <p >}< br/>

 

 

 

Example

1. Edit attributes by group:

Some custom types

Internal class linearbrushconverter: typeconvertergeneral <linearbrush> <br/>{}</P> <p> /// <summary> <br/> // simple linear gradient painter Information <br/> /// </Summary> <br/> [typeconverter (typeof (linearbrushconverter)] <br/> internal class linearbrush <br/>{< br/> Public linearbrush () <br/>{< br/> This. startcolor = color. black; <br/> This. endcolor = color. black; <br/> This. lineardirection = lineargradientmode. horizontal; <br/>}< br/> Public linearbrush (color startcolor, color endcolor, lineargradientmode lineardirection) <br/>{< br/> This. startcolor = startcolor; <br/> This. endcolor = endcolor; <br/> This. lineardirection = lineardirection; <br/>}< br/> private datagridviewcellstyle mcellstyle; <br/> Public datagridviewcellstyle cellstyle <br/> {<br/> Get <br/> {<br/> If (this. mcellstyle = NULL) <br/> This. mcellstyle = new maid (); <br/> return this. mcellstyle; <br/>}< br/> set <br/>{< br/> This. mcellstyle = value; <br/>}< br/> private color mstartcolor; <br/> // <summary> <br/> // obtain or set the starting color of the linear gradient. <br/> /// </Summary> <br/> public color startcolor <br/>{< br/> get {return mstartcolor ;} <br/> set {mstartcolor = value ;}< br/>}< br/> private rectangle mrect; <br/> Public rectangle rect <br/>{< br/> get {return mrect ;}< br/> set {mrect = value ;} <br/>}< br/> private color mendcolor; <br/> // <summary> <br/> // obtain or set the end color of the linear gradient. <br/> /// </Summary> <br/> public color endcolor <br/>{< br/> get {return mendcolor ;} <br/> set {mendcolor = value ;}< br/>}< br/> private lineargradientmode mlineardirection; <br/> /// <summary> <br/> // obtain or set the direction of the linear gradient <br/> /// </Summary> <br/> Public lineargradientmode lineardirection <br/>{< br/> get {return mlineardirection ;} <br/> set {mlineardirection = value ;}< br/>}</P> <p>}

Add an attribute using the linearbrush type in a custom control

Internal partial class controlskinpreview: usercontrol <br/>{< br/> private linearbrush mbackgroundbrush; <br/> // <summary> <br/> // obtain or set the background of the child element <br/> /// </Summary> <br/> Public linearbrush backgroundbrush <br/> {<br/> private linearbrush mbackgroundbrush; <br/> // <summary> <br/> // obtain or set the background of the child element <br/> /// </Summary> <br/> Public linearbrush backgroundbrush <br/> {<br/> Get <br/> {<br/> If (this. mbackgroundbrush = NULL) <br/> This. mbackgroundbrush = new linearbrush (); <br/> return this. mbackgroundbrush; <br/>}< br/> set <br/> {<br/> This. mbackgroundbrush = value; <br/>}< br/>}

You can see the effect in the vs attribute design box.

 

2. Conversion between custom types and strings

Class myclassconverter: typeconvertergeneral <myclass> <br/>{}< br/> [typeconverter (typeof (myclassconverter)] <br/> class myclass <br/>{< br/> Public myclass () <br/>{}< br/> private int mmyint; <br/> Public int Myint <br/>{< br/> get {return mmyint ;}< br/> set {mmyint = value ;} <br/>}< br/> private string mmystring; <br/> Public String mystring <br/>{< br/> get {return mmystring ;} <br/> set {mmystring = value ;}< br/>}</P> <p >}< br/> private void tbtnaddbutton_click (Object sender, eventargs E) <br/>{< br/> This. imnuaddbutton_click (null, null); <br/> myclass M = new myclass (); <br/> M. myint = 10; <br/> M. mystring = "tianfj"; <br/> typeconverter converter = typedescriptor. getconverter (typeof (myclass); <br/> string S = converter. converttostring (m); <br/> console. writeline (s); </P> <p> myclass Mm = converter. convertfromstring (s) as myclass; <br/> console. writeline (mm. tostring (); <br/>}

 

 

End
The above is the code of the "general type converter" and its example. I hope it can reduce the repetitive workload and make some mistakes. Please also point out that it is convenient for everyone to improve together.

 

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.