簡體   English   中英

是否可以控制IExtenderProvider如何格式化Windows Forms Designer代碼中的輸出?

[英]Is it possible to control how IExtenderProvider formats the output in the Windows Forms Designer code?

我有一個實現IExtenderProvider的類

這是有關該接口的出色文章http://www.codeproject.com/Articles/4683/Getting-to-know-IExtenderProvider

基本思想是在Windows窗體設計程序中選擇一個控件,並MyProperty on MyExtender具有“虛擬”屬性MyProperty on MyExtender

工具提示也是如此。

這可以按預期工作,設計器代碼如下所示

this.label1.AutoSize = true;
...
this.myExtender1.SetMyProperty(this.label1, "MyValue");
...
this.label1.Name = "label1";
this.label1.Text = "label1";

僅允許通過屬性網格中的下拉菜單從特定資源文件輸入資源字符串。 現在我要達到的是

this.label1.AutoSize = true;
....
this.myExtender1.SetMyProperty(this.label1, 
                 My.Namespace.Properties.Resources.MyValue);
...
this.label1.Name = "label1";
this.label1.Text = "label1";

這是對我的資源類中的字符串變量的引用。 這個想法是我想從靜態類型中受益(如果我重命名資源,則會得到設計時錯誤而不是運行時錯誤)。

有沒有辦法做到這一點?

蒂姆·范·瓦森霍夫(Tim Van Wassenhove)的標題為“ 將IExtenderProvider的代碼生成隨您的意願而彎曲 ”的文章可能會解決您的問題。

它指出:

探索CodeDomSerializer中,我已經解釋了如何修改Visual Studio設計器為我們生成的代碼。 設計人員使用典型的IExtenderProvider生成初始化器,SetXXX方法和變量聲明...

現在,如果我們對每個組件上生成的SetXXX方法不滿意怎么辦? 問題在於該代碼不是由ConstantsExtenderProvider的序列化程序生成的,而是由Components的序列化程序生成的。 解決此問題的一種簡單方法是將IExtenderProvider中GetXXX方法上的DesignerSerializationVisibilityAttribute設置為Hidden

有了這些丑陋的SetXXX方法,我們有責任做得更好。 為此,我們為ConstantsExtenderProvider實現了一個自定義序列化器:

class ConstantsSerializer<t> : CodeDomSerializer
{
 public override object Serialize(IDesignerSerializationManager manager, object value)
 {
  ConstantsExtenderProvider provider = value as ConstantsExtenderProvider;
 
  CodeDomSerializer baseClassSerializer = manager.GetSerializer(typeof(ConstantsExtenderProvider).BaseType, typeof(CodeDomSerializer)) as CodeDomSerializer;
  CodeStatementCollection statements = baseClassSerializer.Serialize(manager, value) as CodeStatementCollection;
 
  IDesignerHost host = (IDesignerHost)manager.GetService(typeof(IDesignerHost));
  ComponentCollection components = host.Container.Components;
  this.SerializeExtender(manager, provider, components, statements);
 
  return statements;
 }
 
 private void SerializeExtender(IDesignerSerializationManager manager, ConstantsExtenderProvider provider, ComponentCollection components, CodeStatementCollection statements)
 {
  foreach (IComponent component in components)
  {
   Control control = component as Control;
   if (control != null && (control as Form == null))
   {
    CodeMethodInvokeExpression methodcall = new CodeMethodInvokeExpression(base.SerializeToExpression(manager, provider), "SetConstants");
    methodcall.Parameters.Add(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), control.Name));
 
    string[] constants = provider.GetConstants(control);
    if (constants != null)
    {
     StringBuilder sb = new StringBuilder();
     sb.Append("new string[] { ");
 
     foreach (string constant in constants)
     {
      sb.Append(typeof(T).FullName);
      sb.Append(".");
      sb.Append(constant);
      sb.Append(", ");
     }
 
     sb.Remove(sb.Length - 2, 2);
     sb.Append(" }");
 
     methodcall.Parameters.Add(new CodeSnippetExpression(sb.ToString()));
    }
    else
    {
     methodcall.Parameters.Add(new CodePrimitiveExpression(null));
    }
 
    statements.Add(methodcall);
   }
  }
 }
}

現在生成的代碼如下所示:

this.constantsExtenderProvider1.SetConstants(this.button1, new string[] {
    WindowsApplication1.Constants.Operation1,
    WindowsApplication1.Constants.Operation5
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM