我有一个实现IExtenderProvider的类
这里有一篇关于接口http://www.codeproject.com/Articles/4683/Getting-to-know-IExtenderProvider的优秀文章
其基本思想是在windows窗体中选择一个控件,并具有一个“虚拟”属性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";它是对我的资源类中的字符串变量的引用。我的想法是,我想从静态类型中获益(如果我重命名一个资源,我会得到设计时错误,而不是运行时错误)。
有办法做到这一点吗?
发布于 2014-02-13 16:50:01
这篇题为"使IExtenderProvider的代码生成与您的意愿一致“的文章由titled撰写,可以解决您的问题。
它指出:
在探索CodeDomSerializer中,我已经解释了如何修改Visual设计器为我们生成的代码。使用典型的IExtenderProvider,设计器生成初始化器、SetXXX方法和变量声明. 现在,如果我们对每个组件上生成的SetXXX方法不满意怎么办?问题是,这段代码不是由ConstantsExtenderProvider的序列化程序生成的,而是由组件的序列化器生成的。解决此问题的一个简单方法是将我们的DesignerSerializationVisibilityAttribute中的GetXXX方法上的IExtenderProvider设置为隐藏。 有了这些丑陋的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
});https://stackoverflow.com/questions/20418520
复制相似问题