I have benefited a lot from studying anf source code. Many of these ideas are worth learning. Here, Bao Yu has already introduced how ASP. NET forums implements code separation and skin replacement in ASP. NET forums2.0 deep analysis. However, when there are many server-side controls in a custom control, the implementation of the initializeskin MethodCodeIt's a little annoying, for example, looking at the adminsitesettings code. It is really annoying. The modes are the same, such as textbox disablesitereason = Skin. findcontrol ("disablesitereason") as textbox. So today we want to use attribute to simplify it.
First, we need to add an attribute class, which is currently called bindcontrolattribute:
Using system;
Using system. Collections. Generic;
Using system. text;
Using system. reflection;
Namespace aspnetforums. Controls
{
[Attributeusage (attributetargets. FIELD | attributetargets. Property, allowmultiple = false)]
Class bindcontrolattribute: attribute
{
String _ ctrlid;
Public bindcontrolattribute (string ctrlid)
{
_ Ctrlid = ctrlid;
}
Public String controlid
{
Get {return _ ctrlid ;}
}
}
}
This type of attribute function is relatively simple, that is, let this attribute record the ID of the control to which the field is bound.
The second step is to modify skinnedforumwebcontrol, mainly to add a method:
Private void initializefields (control skin)
{
Fieldinfo [] fields = This. GetType (). getfields (bindingflags. nonpublic | bindingflags. instance | bindingflags. declaredonly );
Foreach (fieldinfo fi in fields)
{
If (Fi. isdefined (typeof (bindcontrolattried), false ))
{
Bindcontrolattribute bind = Fi. getcustomattributes (typeof (bindcontrolattrites), false) [0] As bindcontrolattrites;
Object CTRL = Skin. findcontrol (bind. controlid );
Fi. setvalue (this, CTRL );
}
}
}
Actually in FI. isdefined (typeof (bindcontrolattried), false) Here I want to add a condition, that is, the type of the restricted field is system. web. UI. control or its subclass, but failed to succeed after trying several methods. Please give me some advice...
Remember to reference the system. Reflection namespace and change the implementation of the createchildcontrols method:
Protected override void createchildcontrols ()
{
Control Skin = NULL;
If (inlineskin! = NULL)
{
Inlineskin. instantiatein (this );
Initializeskin (this );
}
Else
{
// Load the skin
Skin = loadskin ();
// Initialize the fields
Initializefields (skin); // Add this line
// Initialize the skin
Initializeskin (skin );
Controls. Add (skin );
}
}
At this point, the implementation task is complete. The following is the application. The application is relatively simple. You only need to add this bindcontrolattribute when defining the field. For example:
Uing system;
Using system. collections;
Using system. Web;
Using system. Web. UI;
Using system. Web. UI. webcontrols;
Using aspnetforums. components;
Using aspnetforums. enumerations;
Namespace aspnetforums. Controls
{
/// <Summary>
/// Server Control of the Forum Group list
/// </Summary>
Public class forumgroupview: skinnedforumwebcontrol
{
# Region member Field
Private forumcontext = forumcontext. Current;
Private string skinfilename = "View-ForumGroupView.ascx ";
[Bindcontrol ("forumgrouprepeater")]// Add this line when defining a field
Private repeater;
# Endregion
Public forumgroupview ()
{
// Assign a default Template Name
If (skinfilename = NULL)
Skinfilename = skinfilename;
}
# Endregion
# Region control Initialization
//************************************** *******************************
// Initializeskin
//
/// <Summary>
/// Initializes the user control loaded in createchildcontrols. Initialization
/// Consists of finding well known control names and wiring up any necessary events.
/// </Summary>
///
//************************************** ******************************/
Protected override void initializeskin (control skin)
{
// Repeater = (repeater) skin. findcontrol ("forumgrouprepeater ");// This line is useless.
Databind ();
}
Is it better?
it took me a lot of effort to use reflection for the first time (mainly because I did not read the book carefully :-)). I tried the private fields many times before trying to obtain them. The first two bindingflags seem to have to be added. In addition, I found that the attribute constructor is called only when the getcustomattributes function is called. I don't know if there is any second class?