Create a configurable component (paste) for Microsoft Visual Studio. NET Design Tools

Source: Internet
Author: User
Tags array bool visual studio backup
Visual access in the same way: saving components through the code
Unlike previous design tools, the Win forms of. NET Framework components and other VS. NET design tools rely only on the form's code retention. There is no magical format, no hidden information, but a common code for stability. Of course, like dot and localized strings, you can look at the binary data and the code, but the component state and the contents of the component must be saved through the code. At the same time as you design tools, you will also generate code. If you are dealing with the code, it will be dissected and changed to be more content in the design tool.

The. Net Framework's design tools provide all the backup to take advantage of this feature. All design tools for any type of content you would like to know include:

What information about the state of an object helps to preserve it?

How do I transfer this information back to the existing object?

This question has been briefly discussed in the previous chapters. Again, TypeConverter is the core of the deal. The production code and the profiling Code design tool are related to the specific type of persistinfo named Creationbundle. For example:

[TypeConverter (typeof (Intboolstring.intboolstringconverter))]
public class Intboolstring {
private int intval;
private string Stringval;
private bool Boolval;

Public intboolstring (string s, int I, bool b) {
This.intval = I;
This.stringval =s;
This.boolval = b;
}
public bool bool{
get {return boolval;}
set {boolval = value;}
}

public int int {
get {return intval;}
set {intval = value;}
}

public string String {
get {return stringval;}
set {stringval = value;}
}

public override string ToString () {
return intval + "," + Boolval + "," + stringval;
}

public class Intboolstringconverter:typeconverter {

public override bool CanConvertFrom (
ITypeDescriptorContext context,
Type sourcetype) {
return (Sourcettype = = typeof (String));
}

Public virtual Object ConvertFrom (
ITypeDescriptorContext context,
Object value,
object[] arguments) {

if (value is String) {
String stringvalue = (string) value;
int intvalue;
BOOL Boolvalue;

int commaindex =
Stringvalue.indexof (', ');

if (Commaindex!=-1) {
Intvalue = Int32.
Parse (stringvalue.
Substring (0, Commaindex));
Commaindex = stringvalue.
IndexOf (', ',
Commaindex + 1);
if (Commaindex!=-1) {
int nextcomma = Stringvalue.indexof (', ', Commaindex + 1);
if (Nextcomma!=-1) {
Boolvalue = Boolean.Parse (stringvalue.substring (commaindex+1,
Nextcomma-commaindex));
StringValue = stringvalue.substring (nextcomma+1);
return new Intboolstring (Intval, Boolval, stringvalue);
}

}
}
throw new FormatException ("Can ' t convert '" + stringvalue + "' to intboolstring Object");
}
}



public override Persistinfo Getpersistinfo (ITypeDescriptorContext context, object value) {
If (value is intboolstring) {
Intboolstring IBS = (intboolstring) value;

return new Creationbundle (typeof (Intboolstring), NULL,
New creationargument[] {
New Creationargument (IBS. Int, typeof (Int32)),
New Creationargument (IBS. BOOL, typeof (BOOL)),
New Creationargument (IBS. String, typeof (String)});
}

Return base. Getpersistinfo (context, value);
}
}

public override Object CreateInstance (ITypeDescriptorContext
Context, IDictionary propertyvalues) {
return new intboolstring (int) propertyvalues["int"],
(BOOL) propertyvalues["bool"],
(string) propertyvalue["string"]);
}

public override bool Getcreateinstancesupported (ITypeDescriptorContext context) {
return true;
}

}


The good thing about using Creationbundle objects is that if they have a structure that conforms to the various types of creationargument, you can learn how to store information. When you call typeconverter::createinstance and try to create and initialize objects in this way, the TypeConverter's preset calls Creationbundle::invoke. In the event of an unusable build function, the CreateInstance call takes a IDictionary to allow the object to make more customizations. The IDictionary contains values that are not saved in each name.

Component values are usually composed of multiple objects, and other structures are usually used for this purpose. However, the array is a little bit short, for example, the array has to be copied first, and then copied again at the time of the transfer, and the results are significantly effective; when adding, modifying, or erasing values, the array does not provide intelligent notification. In fact, it is a waste of time to add or delete items if the attributes are returned to the array. Arrays are also snapshot values and cannot be updated if the basic objects do not change.

Conversely, in this case, the. Net Framework uses a collection of ICollection objects that are actually rows. objects can be set up and sent to other objects, while at the same time the items can be kept up to date with the changes in the basic objects. If another object also changes to the set, it will also notify the object. For a. Net Framework design tool that uses collections, you also need to support all attributes that contain get and Set, and that type must be an array of objects that can be retained by the collection. For example:

public class Intcollection:icollection {
Private int[] values;

Public Intcollection (int[] intvalues) {
This.values = (int[]) intvalues.clone ();
}

Public int[] All {
get {
Return (int[]) values. Clone ();
}
set {
Values = (int[]) value. Clone ();
}
}

public int Count {
get {
if (values = = null) {
return 0;
}
return values. Length;
}
}


[Browsable (False)]
public Object SyncRoot {
get {
return this;
}
}

[Browsable (False)]
public bool IsReadOnly {
get {
return false;
}
}

[Browsable (False)]
public bool IsSynchronized {
get {
return true;
}
}
}


The. Net Framework's retention mechanism to save or not save this collection. If the collection is composed of a more advanced type, such as the boolintstring example above, it is necessary to use the TypeConverter associated with the type to establish an effective persistinfo for each item in the set (specifically the VS. NET design tool). Creationbundle).

Component Design Tools
As mentioned earlier, the built-in design tools in the. Net Framework are sufficient to satisfy the multiple requirements of a component. However, the. Net Framework also includes the complete structure of the component design tools. All the design tools are based on the System.ComponentModel.Design.IDesigner interface and are listed as follows:

Public interface IDesigner {

Components associated with this design tool
IComponent Component {get;}

In the design phase of the component,
such as TabControl's "add tab"
Designerverb[] Verbs {get;}

Any resource that is used by the design tool.
The design tool is not available after this call.
void Dispose ();

Call to require the design tool to perform a "preset".
Typically, the response stage is "connected by two" on the component.
Call for motion.
void DoDefaultAction ();

The design tool is initialized with a set of components.
void Initialize (IComponent component);
}


It is not hard to see that IDesigner is straightforward. The design tools are connected through designerattribute and components:

[Designer ("MyNameSpace.Design.MyComponentDesigner, MyNameSpace.DLL")]
public class Mycomponent:component {
}


If DesignerAttribute does not come out of the category, it has to be found in the design tool position to be able to cross the hierarchy. In the preceding example, the preset ComponentDesigner may be at the same time as the element base. Some design tools show the UI, some of which are not displayed. In ComponentDesigner, because a component usually does not have a UI, you can see a diagram representing the object. On the other hand, the Win form control has a design tool that shows the actual control in the design phase.

Map 3: Design phase of Win form control

Note that the image below the design tool is a control that does not display the UI, and the Win-form control for the UI is shown in the form design tool in the display. However, regardless of whether or not, all of these controls are built on the basis of IDesigner. The control's design tool usually intercept the control project in the WindowProc (from the System.WinForms.Design.ControlDesigner design tool can simply overwrite the WndProc method), To perform such complex tasks as clicking on tests. However, for most components, the built-in design tools should already be in use.

Using the design tool service and the infrastructure structure
The. NET Framework design tool in VS. NET exposes a variety of services and infrastructure components that simplify the process or allow design tools to understand the state of the other parts. These services are permanently accessed through Iserviceobjectprovider using the Getserviceobject method. The following is a checklist of some of the special design tools:

Types

 
Describe

IDesignerHost
The main category of any of the top design tools. Methods can be provided to increase service, build and place components, remove components, and perform batch work.

IComponentChangeService
Notifications are provided when new, removed, renamed, or modified components are added.

ISelectionService
Set or obtain the items selected in the current design tool.

IToolboxService
Allow you to experience and modify items and options in the toolbox, and so on.

Iundoservice
Provides a backup to create an active/redo unit, and manages recovery/redo stacking.

IHelpService
Allow you to set a democratic or call it an item.

IMenuCommandService
Allows you to work with the design Tools menu instructions and actions.

IReferenceService
In the design tool, the contents are taken into the object. For example, the name Button1 to the component button1.



IDesignerHost is the foundation of all design tools in VS. NET. IDesignerHost is also Iserviceobjectprovider, which can be used to add and move Ser tasks. It also provides a way to create components to ensure that they are positioned properly. The following are examples of building components using IDesignerHost:

public class Mydesigner:idesigner {

// ?.

Private void Onsurfacedoubleclick (object s, EventArgs e) {
IDesignerHost host =
(IDesignerHost) This.Component.Site.GetServiceObject (typeof (IDesignerHost));
IF (host!= null) {
Object newcomponent = host. Createcomponent (typeof (MyComponent));
Dosomethinginterestingwithcomponent (newcomponent);
}
}

// ?}


Component Grant rights
In the expanded. Net Framework model, the grant structure can also be expanded at the same time. For ease of use, the framework defines a built-in standard-granting method to control whether a component is granted rights at the design-use stage, and the author is free to replace the system.

Add LicenseProviderAttribute to control.
[LicenseProvider (typeof (LicFileLicenseProvider))]
public class Mycontrol:richcontrol {
Establish a new "null" license.
Private License License = null;
Public mycontrol () {
Make the control's construction function effective.
license = Licensemanager.validate (typeof (MyControl), this);
Are there other examples of work performed? }
public override void Dispose () {
if (license!= null) {
License. Dispose ();
license = NULL;
}
}
protected override void Finalize () {
Dispose ();
Base. Finalize ();
}
}


This example can be used to activate the empowerment process using the build support. LicFileLicenseProvider as long as you are looking for a file called <classname>.lic in the category of Assembly, classname must be a complete type name. For example, for String types, the name is System.String.lic. This file can contain string "system.string is a delegated component. If this file is found, the licensemanager.validate will transmit the rights to the object and proceed with the example.

In fact, your personal licensing system is also simple. As long as we build a human being from LicenseProvider, and actually do the Getlicense method. You can log on as a foundational licensing system in which the granted design segment has an item in the file:-

public class Registrylicenseprovider:licenseprovider {
public override License Getlicense (
LicenseContext context,
Type type,
Object instance,
BOOL allowexceptions) {

RegistryKey LicenseKey = Registry.localmachine.
OpenSubKey ("software\\mycompany\\componentlicenses");

if (context. Usagemode = = licenseusagemode.designtime) {
if (LicenseKey!= null && licensekey.getvalue (type. FullName)!= null) {
Return to New Reglicense (this, type);
}
if (allowexceptions) {
throw new LicenseException (type, instance,
"Couldn ' t get design-time license for '" "+
Type. FullName + "'");
}
return null;
}
else {
Return to New Runtimereglicense (this, type);
}
}

Private class Runtimereglicense:license {
public string LicenseKey {
get {
return type. FullName;
}
}
public override void Dispose () {
}


}

Private class Reglicense:license {
Private Registrylicenseprovider owner;
private type type;

Public Reglicense (registrylicenseprovider owner, type type) {
This.owner = owner;
This.type = type;
}

public string LicenseKey {
get {
return type. FullName;
}
}
public override void Dispose () {
}
}

[LicenseProvider (typeof (Registrylicenseprovider))]
public class Mycontrol:control {
}


Components using this license will have a login in the following file:

Hkey_local_machine\software\mycompany\componentlicenses
<type full name>= "true"


Concludes
Writing control in a management code can bring more advantages to the traditional c++/com approach. Microsoft has been planning from the most basic general language stage, spanning to C # and even a group of Visual Basic languages, to provide the most efficient common method of development, minimizing the barriers to building software. The Microsoft. Net Framework is the first large code library sample to develop successfully based on these techniques and principles, and the supported integrated design tools are key to the success of this approach.

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.