ASP.Netコントロール開発シリーズ(七)
[2番目の選択]
前編では、エディターについてそんなにたくさん話しましたが、終わりましたか.いいえ、前編では操作属性のUItypeEditorを紹介しただけです.DataGridのプロパティウィンドウの下にある「プロパティジェネレータ...」を覚えています.そうですか.
「属生ジェネレータ...」をクリックするとその後、IDEはフォームをポップアップし、PropertyGridより使いやすく、DataGridの「国情」に合ったDataGrid属性を操作するインタラクティブなインタフェースを提供します.したがって、ユーザーにはプロパティ・ペイン以外の2番目の選択があります.
ではこの「プロパティジェネレータ...」何ですか.また、UItype Editorではなく、ComponentEditorです.はい、コンポーネントエディタです.プロパティを編集するのではなく、コントロール全体を操作するために使用されます.
次に、コンポーネントエディタを実装するには、どのような作業を行うかを例に示します.
コントロールマスタークラス
[
Designer(typeof(MyDesigner)),
Editor(typeof(MyComponentEditor), typeof(ComponentEditor))
]
public class MyControl :WebControl {
}
ここでは、コンポーネントエディタを容易に呼び出すにはDesignerクラスを使用するため、2つのAttributeを使用してコントロールマスタークラス:DesignerとEditorを記述し、最初にコントロールマスタークラスにデザイナを関連付けます.2番目のAttributeはコントロールマスタークラスにエディタを関連付けており、2番目のパラメータがUITypeEditorではなくComponentEditorになっていることがわかります.
エディタフォームクラス
public class MyComponentEditorForm : System.Windows.Forms.Form {
private MyControl _myControl;
public myControlComponentEditorForm(myControl component) {
InitializeComponent();
_myControl = component;
// _myControl ( TextBox, PropertyGrid )。
}
//
private void okButton_Click(object sender, System.EventArgs e) {
PropertyDescriptor Component _myControl.Property_1 = textBox1.Text , Undo #region PropertyDescriptor Component _myControl.Property_1 = textBox1.Text , Undo
PropertyDescriptorCollection props = TypeDescriptor.GetProperties(_myControl);
try {
PropertyDescriptor property_1 = props["Property_1"];
if (textProperty != null) {
textProperty.SetValue(_myControl, textBox1.Text);
}
}
catch {
}
DialogResult = DialogResult.OK;
Close();
#endregion
}
}
public class MyComponentEditor : WindowsFormsComponentEditor {
//
public override bool EditComponent(ITypeDescriptorContext context, object component, IWin32Window owner) {
MyControl control = component as MyControl;
if (Control == null) {
throw new ArgumentException(" , ", "component");
}
IServiceProvider site = control.Site;// Site , GetService , 。 IComponentChangeService、IDesignerEventService、IDesignerHost、IDesignerOptionService
IComponentChangeService changeService = null;//IComponentChangeService , ComponentChanged ComponentChanging 。 .net fw , VS.net 。
DesignerTransaction transaction = null;//DesignerTransaction , 。
bool changed = false;
try {
if (site != null) {
IDesignerHost designerHost = (IDesignerHost)site.GetService(typeof(IDesignerHost));// 、 、 。 VS.net 。
transaction = designerHost.CreateTransaction(" ");//DesignerTransaction IDesignerHost
changeService = (IComponentChangeService)site.GetService(typeof(IComponentChangeService));
if (changeService != null) {
try {
changeService.OnComponentChanging(control, null);// MemberDescriptor EventDescriptor PropertyDescriptor 。 , 。
}
catch (CheckoutException ex) {// CheckoutException VSS
if (ex == CheckoutException.Canceled)
return false;
throw ex;
}
}
}
try {
//
MyComponentEditorForm form = new MyComponentEditorForm(control);
if (form.ShowDialog(owner) == DialogResult.OK) {//from.ShowDialog(owner) from owner 。
changed = true;
}
}
finally {
if (changed && changeService != null) {// ,
changeService.OnComponentChanged(Control, null, null, null);// , null
}
}
}
finally {
if (transaction != null) {
if (changed) {// ,
transaction.Commit();
}
else {
transaction.Cancel();
}
}
}
return changed;
}
}
, , ,
Designer
“WYSWYG”
: DataGrid , ?
, Designer
。WebForm WinForm System.ComponentModel.Design.ComponentDesigner, , ,WebForm IE ,WinForm GDI+ 。 WinForm , WebForm Designer 。
, 。 。
, DesignerVerbCollection Verbs{get;}
Verbs:
public class MyControlDesigner : ControlDesigner {
private DesignerVerbCollection designerVerbs;
public override DesignerVerbCollection Verbs {
get {
if (designerVerbs == null) {
designerVerbs = new DesignerVerbCollection();
designerVerbs.Add(new DesignerVerb(" ", new EventHandler(this.OnControlPropertyBuilder)));// ,
}
return designerVerbs;
}
}
private void OnControlPropertyBuilder(object sender, EventArgs e) {
MyComponentEditor compEditor = new MyComponentEditor();
compEditor.EditComponent(Component);
}
}
, 。
Designer “ ”, , :
public override void Initialize(IComponent component) {
if (!(component is MyControl)) {
throw new ArgumentException("Component must be a MyControl control.", "component");
}
base.Initialize(component);
}
public override string GetDesignTimeHtml() {
MyControl control = (MyControl)Component;
string designTimeHtml = String.Empty;
try {
designTimeHtml = base.GetDesignTimeHtml();
}
catch (Exception e) {
designTimeHtml = GetErrorDesignTimeHtml(e);
}
return designTimeHtml;
}
protected override string GetEmptyDesignTimeHtml() {
return CreatePlaceHolderDesignTimeHtml(" . ");
}
protected override string GetErrorDesignTimeHtml(Exception e) {
return CreatePlaceHolderDesignTimeHtml(" .");
}
, 。
:
1、 ( 。), GetDesignerTimeHtml null 。
2、ControlDesigner GetDesignTimeHtml RenderControl HTML , , 。 ? , overrideGetDesignTimeHtml , , OnPerRender Render , OnPerRender , , , 。