问题描述
我有一个类实现 IExtenderProvider
下面是关于该接口 HTTP:/ /www.$c$cproject.com/Articles/4683/Getting-to-know-IExtenderProvider
其基本思想是选择在Windows窗体desinger控制,并有一个虚拟财产在myProperty的MyExtender
工具提示不一样的。
这工作正常,并设计code看起来像这样
this.label1.AutoSize = TRUE;
...
this.myExtender1.SetMyProperty(this.label1myvalue的);
...
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;
这是我的资源类的引用字符串变量。我们的想法是,我想从静态类型利润(如果我重新命名的资源,我得到了设计时间错误,而不是运行时错误)。
有没有办法才达到这一点?
这一篇文章,题为的的添范·沃森霍夫可以解决你的问题。
它指出:
类ConstantsSerializer< T> :codeDomSerializer
{
公众覆盖对象序列(IDesignerSerializationManager经理,对象值)
{
ConstantsExtenderProvider提供商=价值ConstantsExtenderProvider;
codeDomSerializer baseClassSerializer = manager.GetSerializer(typeof运算(ConstantsExtenderProvider).BaseType的typeof(codeDomSerializer))为codeDomSerializer;
codeStatementCollection陈述= baseClassSerializer.Serialize(经理,价值)为codeStatementCollection;
IDesignerHost的主机=(IDesignerHost的)manager.GetService(typeof运算(IDesignerHost的));
ComponentCollection成分= host.Container.Components;
this.SerializeExtender(经理,供应商,组件,报表);
return语句;
}
私人无效SerializeExtender(IDesignerSerializationManager经理,ConstantsExtenderProvider提供商,ComponentCollection组件,codeStatementCollection语句)
{
的foreach(在组件IComponent的组件)
{
控制控制=组件作为控制;
如果(控制= NULL和放大器;!及(控制,表== NULL))
{
codeMethodInvokeEx pression methodcall =新的codeMethodInvokeEx pression(base.SerializeToEx pression(经理,供应商),SetConstants);
methodcall.Parameters.Add(新的codeFieldReferenceEx pression(新的codeThisReferenceEx pression(),control.Name));
字符串[]常量= provider.GetConstants(控制);
如果(常量!= NULL)
{
StringBuilder的SB =新的StringBuilder();
sb.Append(新的String [] {);
的foreach(常量字符串常量)
{
sb.Append(typeof运算(T).FullName);
sb.Append(。);
sb.Append(常数);
sb.Append(,);
}
sb.Remove(sb.Length - 2,2);
sb.Append(});
methodcall.Parameters.Add(新的codeSnippetEx pression(sb.ToString()));
}
其他
{
methodcall.Parameters.Add(新的codePrimitiveEx pression(空));
}
statements.Add(methodcall);
}
}
}
}
this.constantsExtenderProvider1.SetConstants(this.button1,新的String [] {
WindowsApplication1.Constants.Operation1,
WindowsApplication1.Constants.Operation5
});
I have a class that implements IExtenderProvider
Here is a great article about that interface http://www.codeproject.com/Articles/4683/Getting-to-know-IExtenderProvider
The basic idea is to select a control in the windows forms desinger and have a "virtual" property MyProperty on MyExtender
The tooltip does the same.
This works as expected and the designer code looks like this
this.label1.AutoSize = true;
...
this.myExtender1.SetMyProperty(this.label1, "MyValue");
...
this.label1.Name = "label1";
this.label1.Text = "label1";
It is only allowed to input resource strings from a specific resource file via a drop down menu in the property grid. Now what I want to achive is this
this.label1.AutoSize = true;
....
this.myExtender1.SetMyProperty(this.label1,
My.Namespace.Properties.Resources.MyValue);
...
this.label1.Name = "label1";
this.label1.Text = "label1";
which is the reference to the string variable in my resource class.The idea is that I want to profit from the static typing (If I rename a resource I get design time errors rather than runtime errors).
Is there a way to achive this?
This article titled "Bending the code generation of IExtenderProvider to your will" by Tim Van Wassenhove may solve your problem.
It states:
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
});
这篇关于是否有可能控制IExtenderProvider如何格式在Windows窗体设计code的输出?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!