ไลบรารีตัวควบคุม Ajax Control Toolkit มีตัวควบคุมเพิ่มเติมบางส่วน คุณสามารถเพิ่มเอฟเฟ็กต์ Ajax ให้กับตัวควบคุมทั่วไปได้อย่างง่ายดาย ตัวอย่างเช่น คุณสามารถใช้ตัวควบคุม AutoCompleteExtender เพื่อเพิ่มเอฟเฟกต์ Ajax ให้สมบูรณ์อัตโนมัติลงในกล่องข้อความ แน่นอนว่านี่ไม่ใช่สิ่งที่บทความนี้ต้องการจะพูดถึง
เพิ่มชุดเครื่องมือควบคุม Ajax ลงในกล่องเครื่องมือ Visual Studio 2008 เปิดไฟล์ aspx ใหม่แล้วลากกล่องข้อความลงไป ในเวลานี้ มีบางอย่างที่น่าสนใจเกิดขึ้น ในแผง SmartTasks ของกล่องข้อความ ลิงก์ไปยัง "เพิ่มส่วนขยาย..." ปรากฏขึ้นจริง ๆ! ฉันพยายามลากปุ่มและแผงอีกครั้ง และไม่มีข้อยกเว้น ลิงก์ "เพิ่มส่วนขยาย..." ปรากฏที่ด้านล่างของแผง SmartTasks ของแต่ละตัวควบคุม
เมื่อเร็วๆ นี้ ฉันกำลังวางแผนที่จะใช้ฟังก์ชันนามธรรม เช่น การบันทึก การลบ และการปิดเพจลงในการดำเนินการ แต่ละการดำเนินการจะสอดคล้องกับการควบคุมเว็บแบบกำหนดเอง หลังจากแนบตัวควบคุมการดำเนินการเข้ากับตัวควบคุมเป้าหมาย (เช่น ปุ่ม) แล้ว ตัวควบคุมเป้าหมายจะมีฟังก์ชัน เช่น การบันทึก การลบ และการปิดหน้า วิธีแนบการดำเนินการกับตัวควบคุมปุ่มในตัวออกแบบ WebForm ได้อย่างง่ายดาย สิ่งที่ฉันต้องการคือ "เพิ่มส่วนขยาย..."
เพื่อนที่ได้พัฒนาตัวควบคุมเซิร์ฟเวอร์แบบกำหนดเองควรรู้ว่าหากคุณต้องการเพิ่ม SmartTasks ให้กับตัวควบคุม คุณจะต้องแทนที่คุณสมบัติ ActionLists ของ ControlDesigner และใช้ DesignerActionList ของคุณเอง แน่นอนว่ากล่องข้อความไม่ทราบว่ามี AjaxControlToolkit อยู่ ดังนั้น "เพิ่มส่วนขยาย..." จึงไม่ได้เพิ่ม DesignerActionMethodItem ลงไป ดังนั้น กรอบงาน .net จึงมีอินเทอร์เฟซบางประเภทที่ช่วยให้เราสามารถ "แทรก" DesignerActionItem แบบไดนามิกลงในส่วนควบคุมอื่นๆ ได้หรือไม่
จากการวิจัยบน AjaxControlToolKit.dll ฉันพบว่าผู้ออกแบบส่วนควบคุมแบบขยายเหล่านี้ไม่มีส่วนรับผิดชอบในการจัดเตรียมการดำเนินการ "เพิ่มส่วนขยาย" พวกเขามีหน้าที่รับผิดชอบในการจัดหาเนื้อหาส่วนขยายที่สอดคล้องกับส่วนขยายที่เกี่ยวข้องเท่านั้น ดังนั้นรายการเดียวจึงมาจาก นักออกแบบเว็บฟอร์มของ Visual studio มาเรียนกันเถอะ ใช้ตัวสะท้อนแสงเพื่อเปิด Microsoft Visual Studio 9.0Common7IDEMicrosoft.Web.Design.Client.dll และค้นหาอินเทอร์เฟซ IWebSmartTasksProvider อินเทอร์เฟซนี้มีเมธอด GetDesignerActionLists ค่าที่ส่งคืนของวิธีนี้ควรเป็นเนื้อหาที่แสดงในแผง SmartTasks . อินเทอร์เฟซนี้มีคลาสการใช้งานสามคลาส ได้แก่ DataFormDesigner, DataFormXslValueOfDesigner และ ElementDesigner สามารถอนุมานได้จากการตั้งชื่อคลาสทั้งสามนี้ว่า ElementDesigner ควรเป็นคลาสการใช้งานที่ใช้บ่อยที่สุด วิธีการ GetDesignerActionLists ของ ElementDesigner ถูกนำไปใช้ดังนี้:
1: DesignerActionListCollection IWebSmartTasksProvider.GetDesignerActionLists()
2: {
3: DesignerActionListCollection ส่วนประกอบการกระทำ = null;
4: ถ้า (this.Designer != null)
5: {
6: บริการ DesignerActionService = (DesignerActionService) base.DesignerHost.GetService(typeof(DesignerActionService));
7: ถ้า (บริการ != null)
8: {
9: componentActions = service.GetComponentActions (this.Designer.Component);
10: }
11: }
12: ถ้า (componentActions == null)
13: {
14: ComponentActions = ใหม่ DesignerActionListCollection();
15: }
16: ส่งคืนการดำเนินการส่วนประกอบ;
17: }
18:
19:
20:
ยี่สิบเอ็ด:
จากโค้ดด้านบน คุณจะเห็นว่า DesignerActionListCollection สุดท้ายถูกกำหนดโดย GetComponentActions ของคลาส System.ComponentModel.Design.DesignerActionService ภายใต้แอสเซมบลี System.Design และ Microsoft.Web.Design.WebFormDesigner ภายใต้ Microsoft.Web.Design.Client dll +WebDesignerActionService สืบทอดคลาสนี้และการนำไปใช้งานจะเป็นดังนี้:
1: การแทนที่ที่ได้รับการปกป้องถือเป็นโมฆะ GetComponentDesignerActions (ส่วนประกอบ IComponent, DesignerActionListCollection actionLists)
2: {
3: การควบคุมการควบคุม = ส่วนประกอบเป็นการควบคุม;
4: ผู้ปกครอง ElementDesigner = null;
5: ถ้า (ควบคุม != null)
6: {
7: parent = ElementDesigner.GetElementDesigner(ควบคุม);
8: }
9: ถ้า ((พาเรนต์ == null) || !parent.InTemplateMode)
10: {
11: base.GetComponentDesignerActions (ส่วนประกอบ, actionLists);
12: ถ้า ((พาเรนต์ != null) && (parent.Designer != null))
13: {
14: ผู้ออกแบบ ControlDesigner = parent.Designer เป็น ControlDesigner;
15: ถ้า ((ผู้ออกแบบ != null) && (designer.AutoFormats.Count > 0))
16: {
17: actionLists.Insert(0, ใหม่ AutoFormatActionList(พาเรนต์));
18: }
19: }
20: ถ้า ((พาเรนต์ != null) && (parent.Element != null))
ยี่สิบเอ็ด: {
22: IWebDataFormElementCallback dataFormElementCallback = parent.Element.GetDataFormElementCallback();
23: ถ้า (dataFormElementCallback != null)
ยี่สิบสี่: {
25: รายการ DataFormElementActionList = DataFormElementActionList ใหม่ (parent, parent.Control, dataFormElementCallback);
26: actionLists.Add(รายการ);
27: DataFormElementActionList.ModifyActionListsForListControl(actionLists, รายการ);
28: }
29: }
30: ถ้า (((พาเรนต์ != null) && (parent.Designer != null)) && parent.DocumentDesigner.ExtenderControlHelper.ProvidesActionLists)
31: {
32: parent.DocumentDesigner.ExtenderControlHelper.AddActionLists (พาเรนต์, actionLists);
33: }
34: }
35: ถ้า ((พาเรนต์ != null) && (parent.TemplateEditingUI != null))
36: {
37: actionLists.Add(TemplateEditingActionList ใหม่ (parent.TemplateEditingUI, parent.Element));
38: }
39: }
40:
41:
42:
43:
ในวิธีนี้มีย่อหน้านี้:
1: if (((parent != null) && (parent.Designer != null)) && parent.DocumentDesigner.ExtenderControlHelper.ProvidesActionLists)
2: {
3: parent.DocumentDesigner.ExtenderControlHelper.AddActionLists (พาเรนต์, actionLists);
4: }
ดูเหมือนว่ามีการเพิ่มการกระทำ "เพิ่มส่วนขยาย" ที่นี่ ดูการใช้งาน ExtenderControlHelper.AddActionLists ต่อไป:
1: โมฆะสาธารณะ AddActionLists (องค์ประกอบ ElementDesigner, รายการ DesignerActionListCollection)
2: {
3: list.Add(ใหม่ ControlExtenderActionList(องค์ประกอบ));
4: ส่วนประกอบ ExtenderControl = element.Designer.Component เป็น ExtenderControl;
5: การควบคุมการควบคุม = element.Designer.Component เป็นการควบคุม;
6: ถ้า ((ส่วนประกอบ == null) && (ควบคุม != null))
7: {
8: บริการ IExtenderInformationService = (IExtenderInformationService) control.Site.GetService(typeof(IExtenderInformationService));
9: ถ้า (บริการ != null)
10: {
11: foreach (การควบคุม control3 ใน service.GetAppliedExtenders(การควบคุม))
12: {
13: list.Add(ใหม่ HoistedExtenderActionList(element.Designer, control3));
14: }
15: }
16: }
17: }
18:
19:
20:
ยี่สิบเอ็ด:
ประโยคแรกในเมธอดนี้คือ list.Add(new ControlExtenderActionList(element)) ControlExtenderActionList สืบทอด System.ComponentModel.Design.DesignerActionList วิธีการ GetSortedActionItems ถูกกำหนดไว้ดังนี้:
1: การแทนที่สาธารณะ DesignerActionItemCollection GetSortedActionItems()
2: {
3: องค์ประกอบการควบคุม = (การควบคุม) this._htmlDesigner.Component;
4: รายการ DesignerActionItemCollection = ใหม่ DesignerActionItemCollection();
5: บริการ IExtenderInformationService = (IExtenderInformationService) ส่วนประกอบ.Site.GetService(typeof(IExtenderInformationService));
6: หมวดหมู่สตริง = SR.GetString(SR.Ids.SmartTasksLabelExtenderSection, CultureInfo.CurrentUICulture);
7: ถ้า (บริการ IsControlExtendible (ส่วนประกอบ))
8: {
9: สตริง displayName = SR.GetString(SR.Ids.SmartTasksAddExtender, CultureInfo.CurrentUICulture);
10: items.Add(DesignerActionMethodItem ใหม่ (สิ่งนี้, "AddExtender", displayName, หมวดหมู่, จริง));
11: }
12: ถ้า (บริการ IsControlExtensed (ส่วนประกอบ))
13: {
14: string str3 = SR.GetString(SR.Ids.SmartTasksRemoveExtender, CultureInfo.CurrentUICulture);
15: items.Add(DesignerActionMethodItem ใหม่ (นี่, "RemoveExtender", str3, หมวดหมู่, จริง));
16: }
17: คืนสินค้า;
18: }
19:
ตอนนี้เป็นที่ชัดเจนว่าการดำเนินการ "เพิ่มส่วนขยาย" ได้รับการฮาร์ดโค้ดในตัวออกแบบเว็บฟอร์มของ Visual Studio เฟรมเวิร์ก .net ไม่มีอินเทอร์เฟซที่เกี่ยวข้องสำหรับเราในการเพิ่มการดำเนินการที่คล้ายกัน แต่เอฟเฟกต์ที่ฉันต้องการคือเพิ่มการกระทำ "เพิ่มการกระทำ" ดังนั้นฉันจึงไม่สามารถอ้างอิงถึงวิธี AjaxControlToolkit เพื่อให้บรรลุเป้าหมายได้ ฉันควรมองหาวิธีอื่น
ย้อนกลับ และตรวจสอบเมธอด GetComponentActions ของคลาส Microsoft.Web.Design.WebFormDesigner+WebDesignerActionService อีกครั้ง และค้นหาคำจำกัดความของคลาสพื้นฐาน System.Web.UI.Design.WebFormsDesignerActionService (ภายใต้แอสเซมบลี System.Design) ดังนี้:
1: การแทนที่ที่ได้รับการปกป้องถือเป็นโมฆะ GetComponentDesignerActions (ส่วนประกอบ IComponent, DesignerActionListCollection actionLists)
2: {
3: ถ้า (ส่วนประกอบ == null)
4: {
5: โยน ArgumentNullException ใหม่ ("ส่วนประกอบ");
6: }
7: ถ้า (actionLists == null)
8: {
9: โยน ArgumentNullException ใหม่ ("actionLists");
10: }
11: ไซต์ IServiceContainer = องค์ประกอบไซต์เป็น IServiceContainer;
12: ถ้า (ไซต์!= null)
13: {
14: บริการ DesignerCommandSet = (DesignerCommandSet) site.GetService(typeof(DesignerCommandSet));
15: ถ้า (บริการ != null)
16: {
17: รายการ DesignerActionListCollection = service.ActionLists;
18: ถ้า (รายการ != null)
19: {
20: actionLists.AddRange (รายการ);
ยี่สิบเอ็ด: }
ยี่สิบสอง: }
23: ถ้า ((actionLists.Count == 0) || ((actionLists.Count == 1) && (actionLists[0] คือ ControlDesigner.ControlDesignerActionList)))
ยี่สิบสี่: {
25: คำกริยา DesignerVerbCollection = service.Verbs;
26: ถ้า ((กริยา != null) && (กริยานับ != 0))
27: {
28: DesignerVerb[] array = ใหม่ DesignerVerb[verbs.Count];
29: กริยา.CopyTo(อาร์เรย์, 0);
30: actionLists.Add(DesignerActionVerbList ใหม่ (อาร์เรย์));
31: }
32: }
33: }
34: }
35:
36:
37:
38:
จากการศึกษาโค้ดข้างต้น เราจะเห็นว่า DesignerActionListCollection ถูกส่งคืนโดยแอตทริบิวต์ ActionLists ของบริการ DesignerCommandSet และบริการนี้ได้มาจากไซต์ของส่วนประกอบ ตราบใดที่ฉันเขียน DesignerCommandSet อื่น และตรวจสอบให้แน่ใจว่า DesignerCommandSet ถูกนำออกจาก เว็บไซต์เป็นของฉัน เพียงเขียนบริการนี้ ในที่สุดก็พบจุดเริ่มต้นแล้ว นี่คือวิธีการเฉพาะ
ขั้นแรก สร้างคลาสที่สืบทอด DesignerCommandSet ดังนี้:
1: MyDesignerCommandSet คลาสสาธารณะ : DesignerCommandSet
2: {
3: ComponentDesigner ส่วนตัว _componentDesigner;
4:
5: MyDesignerCommandSet สาธารณะ (ComponentDesigner componentDesigner)
6: {
7: _componentDesigner = นักออกแบบส่วนประกอบ;
8: }
9:
10: แทนที่สาธารณะ ICollection GetCommands (ชื่อสตริง)
11: {
12: ถ้า (name.Equals("ActionLists"))
13: {
14: กลับ GetActionLists();
15: }
16: กลับฐาน GetCommands (ชื่อ);
17: }
18:
19: DesignerActionListCollection GetActionLists() ส่วนตัว
20: {
21: //รับ DesignerActionLists ดั้งเดิมของตัวควบคุมก่อน
22: รายการ DesignerActionListCollection = _componentDesigner.ActionLists;
ยี่สิบสาม:
24: //เพิ่ม "Add Action" DesignerActionList
25: list.Add(ใหม่ ActionList(_componentDesigner));
26: รายการส่งคืน;
27: }
28:
29: ActionList คลาสภายใน : DesignerActionList
30: {
31: DesignerActionItemCollection ส่วนตัว _actions;
32:
33: ActionList สาธารณะ (ผู้ออกแบบ IDesigner)
34: : ฐาน(ผู้ออกแบบส่วนประกอบ)
35: {
36: }
37: การแทนที่สาธารณะ DesignerActionItemCollection GetSortedActionItems()
38: {
39: ถ้า (_actions == null)
40: {
41: const string actionCategory = "การกระทำ";
42: _actions = DesignerActionItemCollection ใหม่ ();
43: _actions.Add(DesignerActionMethodItem ใหม่ (นี่คือ "AddAction", "เพิ่มการกระทำ...", actionCategory, จริง));
44: }
45: กลับ _การกระทำ;
46: }
47:
48: AddAction() เป็นโมฆะสาธารณะ
49: {
50: //เพิ่มตรรกะการดำเนินการ ละไว้
51: }
52: }
53: }
ขั้นตอนต่อไปคือวิธีทำให้ Site ServiceProvider ของส่วนประกอบส่งคืนบริการของตัวเอง วิธีการคือการเขียนไซต์ด้วยตัวเองและทำให้ไซต์ของคอมโพเนนต์เป็นวัตถุของคลาส SIte ที่คุณเขียน
คำจำกัดความของคลาสไซต์ที่ฉันเขียนมีดังนี้:
1: SiteProxy ระดับสาธารณะ: ISite, IServiceContainer
2: {
3: ISite_site ส่วนตัว;
4: ComponentDesigner ส่วนตัว _designer;
5:
6: SiteProxy สาธารณะ (ไซต์ ISite, ผู้ออกแบบ ComponentDesigner)
7: {
8: _ไซต์ = ไซต์;
9: _designer = นักออกแบบ;
10:
11: }
12:
13: #สมาชิก ISite ในภูมิภาค
14:
15: IComponentComponent สาธารณะ
16: {
17: รับ { กลับ _site.Component;
18: }
19:
20: สาธารณะ System.ComponentModel.IContainer คอนเทนเนอร์
ยี่สิบเอ็ด: {
22: รับ { กลับ _site.Container }
ยี่สิบสาม: }
ยี่สิบสี่:
25: สาธารณะ boolDesignMode
26: {
27: รับ { กลับ _site.DesignMode }
28: }
29:
30: ชื่อสตริงสาธารณะ
31: {
32: รับ { กลับ _site.Name }
33: ตั้งค่า { _site.Name = ค่า;
34: }
35:
36: #สิ้นสุดภูมิภาค
37:
38: #ภูมิภาค IServiceProvider สมาชิก
39:
40: GetService วัตถุสาธารณะ (ประเภท serviceType)
41: {
42: บริการวัตถุ = _site.GetService(serviceType);
43:
44: ถ้า (serviceType == typeof(DesignerCommandSet) && !(_designer.Component คือ ExtenderControl))
45: {
46: ถ้า (บริการ == null || !(บริการคือ MyDesignerCommandSet))
47: {
48: ถ้า (บริการ != null)
49: {
50: RemoveService(ประเภทของ(DesignerCommandSet));
51: }
52: //ส่งคืน DesignerCommandSet ที่เขียนด้วยตัวเอง
53: บริการ = ใหม่ MyDesignerCommandSet(_designer);
54: AddService(ประเภทของ(DesignerCommandSet), บริการ);
55: }
56: }
57: บริการส่งคืน;
58: }
59:
60: #สิ้นสุดภูมิภาค
61:
62: #region สมาชิก IServiceContainer
63:
64: AddService สาธารณะเป็นโมฆะ (ประเภท serviceType, ServiceCreatorCallback โทรกลับ, บูลโปรโมต)
65: {
66: (_site เป็น IServiceContainer).AddService(serviceType, โทรกลับ, เลื่อนระดับ);
67: }
68:
69: AddService โมฆะสาธารณะ (ประเภท serviceType, ServiceCreatorCallback โทรกลับ)
70: {
71: (_site เป็น IServiceContainer).AddService(serviceType, โทรกลับ);
72: }
73:
74: AddService โมฆะสาธารณะ (ประเภท serviceType, object serviceInstance, boolpromote)
75: {
76: (_site เป็น IServiceContainer).AddService(serviceType, serviceInstance, ส่งเสริม);
77: }
78:
79: AddService โมฆะสาธารณะ (ประเภท serviceType, object serviceInstance)
80: {
81: (_ไซต์เป็น IServiceContainer).AddService(serviceType, serviceInstance);
82: }
83:
84: โมฆะสาธารณะ RemoveService(ประเภท serviceType, บูลส่งเสริม)
85: {
86: (_site เป็น IServiceContainer).RemoveService(serviceType, เลื่อนระดับ);
87: }
88:
89: โมฆะสาธารณะ RemoveService(ประเภท serviceType)
90: {
91: (_ไซต์เป็น IServiceContainer).RemoveService(serviceType);
92: }
93:
94: #สิ้นสุดภูมิภาค
95: }
ในวิธีการ GetService ของไซต์นี้ ให้กำหนดประเภทบริการที่จะได้รับ หากเป็น DesignerCommandSet ให้ส่งคืน MyDesignerCommandSet ที่คุณสร้างขึ้น
ขั้นตอนต่อไปคือวิธีเปลี่ยนไซต์ของส่วนประกอบให้เป็น SiteProxy ที่เขียนด้วยตัวเอง วิธีหนึ่งคือการเพิ่มตัวควบคุมแบบกำหนดเองและเปลี่ยนไซต์ของตัวควบคุมอื่น ๆ ในคอนเทนเนอร์ในวิธีการเตรียมใช้งานของ ControlDesigner ของตัวควบคุม คุณจะต้องลากตัวควบคุมลงใน WebForm เพื่อเปลี่ยนไซต์ของตัวควบคุมอื่น ๆ วิธีการคือการเขียนแพ็คเกจ vs และบันทึกเหตุการณ์ที่เกี่ยวข้องของตัวออกแบบเว็บฟอร์มในแพ็คเกจ แนวทางแรกมีการแนะนำด้านล่าง:
เพิ่มการควบคุมใหม่ที่สืบทอดมาจากการควบคุมที่เรียกว่า ActionManager การควบคุมนี้ไม่จำเป็นต้องเพิ่มฟังก์ชันใดๆ คุณจำเป็นต้องสร้าง ControlDesigner เท่านั้น รหัสหลักของคลาส ControlDesigner เป็นดังนี้:
1: ActionManagerDesigner คลาสสาธารณะ: ControlDesigner
2: {
3: IDesignerHost ส่วนตัว _host;
4: IDictionary ส่วนตัว <IComponent, ISite> _components;
5:
6: โมฆะการแทนที่สาธารณะเริ่มต้น (องค์ประกอบ IComponent)
7: {
8: ฐานเริ่มต้น (ส่วนประกอบ);
9:
10: _components = พจนานุกรมใหม่ <IComponent, ISite>();
11:
12: _host = GetService(typeof(IDesignerHost)) เป็น IDesignerHost;
13: ถ้า (_host != null)
14: {
15: //แทนที่ไซต์ด้วยการควบคุมที่มีอยู่
16: กระบวนการส่วนประกอบ();
17:
18: บริการ IComponentChangeService =
19: _host.GetService(typeof(IComponentChangeService)) เป็น IComponentChangeService;
20: ถ้า (บริการ != null)
ยี่สิบเอ็ด: {
22: บริการ ComponentAdded += ComponentAdded;
23: service.ComponentRemoving += การลบส่วนประกอบ;
ยี่สิบสี่: }
25: }
26: }
27:
28: #regionProcessComponent
29:
30: โมฆะส่วนตัว ProcessComponent()
31: {
32: ส่วนประกอบ ComponentCollection = _host.Container.Components;
33: foreach (องค์ประกอบ IComponent ในส่วนประกอบ)
34: {
35: ถ้า (ส่วนประกอบคือ ActionControl)
36: ดำเนินการต่อ;
37: ProcessComponentSite (ส่วนประกอบ);
38: }
39: }
40:
41: #สิ้นสุดภูมิภาค
42:
43: #region แทนที่ไซต์
44:
45: /// <สรุป>
46: /// แทนที่ Site ดั้งเดิมของ Component ด้วย SiteProxy
47: /// </สรุป>
48: โมฆะส่วนตัว ProcessComponentSite (องค์ประกอบ IComponent)
49: {
50: ผู้ออกแบบ ComponentDesigner = _host.GetDesigner (ส่วนประกอบ) เป็น ComponentDesigner
51: _components[ส่วนประกอบ] = ส่วนประกอบไซต์;
52: component.Site = SiteProxy ใหม่ (component.Site ผู้ออกแบบ);
53: }
54:
55: /// <สรุป>
56: /// คืนค่าไซต์ดั้งเดิมของส่วนประกอบ
57: /// </สรุป>
58: /// <param name="component"></param>
59: โมฆะส่วนตัว RestoreComponentSite (ส่วนประกอบ IComponent)
60: {
61: ถ้า (_components.ContainsKey (ส่วนประกอบ))
62: {
63: ไซต์ ISite = _components[ส่วนประกอบ];
64: ส่วนประกอบไซต์ = ไซต์;
65: _components.Remove(ส่วนประกอบ);
66: }
67: }
68:
69: #สิ้นสุดภูมิภาค
70:
71: #region บนคอมโพเนนต์ เพิ่ม ลบ เปลี่ยนแปลง
72:
73: โมฆะส่วนตัว ComponentRemoving (ผู้ส่งวัตถุ ComponentEventArgs e)
74: {
75: ถ้า (e.Component คือ ActionControl)
76: {
77: กลับ;
78: }
79: //เมื่อลบ Component จะต้องคืนค่าคุณสมบัติของ Site มิฉะนั้น Site ดั้งเดิมจะยังคงอยู่ใน DesignerHost
80: //เมื่อเพิ่มส่วนประกอบที่มีชื่อเดียวกันด้วยวิธีนี้ จะมีการรายงานข้อผิดพลาด "ชื่อส่วนประกอบที่ซ้ำกัน"
81: RestoreComponentSite (e. Component);
82: }
83:
84:
85: โมฆะส่วนตัว ComponentAdded (ผู้ส่งวัตถุ ComponentEventArgs e)
86: {
87: ถ้า (e.Component คือ ActionControl)
88: {
89: กลับ;
90: }
91: ProcessComponentSite (e. ส่วนประกอบ);
92: }
93:
94: #สิ้นสุดภูมิภาค
95:
96: #กำจัดภูมิภาค
97:
98: ป้องกันแทนที่เป็นโมฆะกำจัด (การกำจัดบูล)
99: {
100: ถ้า (_โฮสต์ != โมฆะ)
101: {
102: บริการ IComponentChangeService =
103: _host.GetService(typeof(IComponentChangeService)) เป็น IComponentChangeService;
104: ถ้า (บริการ != null)
105: {
106: service.ComponentAdded -= เพิ่มส่วนประกอบแล้ว;
107: service.ComponentRemoving -= การลบส่วนประกอบ;
108: }
109: }
110: ฐาน.ทิ้ง(ทิ้ง);
111: }
112:
113: #สิ้นสุดภูมิภาค
114: }
ณ จุดนี้ ตราบใดที่คุณลากตัวควบคุม ActionManager ลงในตัวออกแบบเว็บฟอร์ม คุณจะเห็นลิงก์ "เพิ่มการดำเนินการ..." บนแผงงานอัจฉริยะของตัวควบคุมอื่นๆ อย่างไรก็ตาม วิธีการนี้จำเป็นต้องวางการควบคุมเพิ่มเติมในตัวออกแบบเว็บฟอร์ม การควบคุมนี้มีประโยชน์เฉพาะในเวลาออกแบบและไม่มีประโยชน์เมื่อรันไทม์ ดังนั้นแนวทางที่ดีที่สุดคือการพัฒนาแพ็คเกจเทียบกับ ในวิธี Initialize ของแพ็คเกจ ให้ลงทะเบียนเหตุการณ์ DesignerCreated ของ IDesignerEventService จากนั้นบรรลุวัตถุประสงค์ของการเปลี่ยนแปลงไซต์ควบคุมผ่าน IDesignerHost และ IComponentChangeService การใช้งานเฉพาะจะคล้ายกับข้างต้น ดังนั้นฉันจะไม่เขียนมันอีกต่อไป