C# CodeDomSerializer输出排序
我已经创建了一个组件来为我们的项目进行本地化。我遇到的问题是,我输出的注入InitializeComponent的代码发生得太晚了 范例C# CodeDomSerializer输出排序,c#,custom-controls,designer,C#,Custom Controls,Designer,我已经创建了一个组件来为我们的项目进行本地化。我遇到的问题是,我输出的注入InitializeComponent的代码发生得太晚了 范例 this.components = new System.ComponentModel.Container(); System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ucHome)
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ucHome));
this.localizationResourceManager1 = new Compass0.Localization.LocalizationResourceManager(this.components);
//Other designer code to create controls (this is all in the first block of code in InitializeComponent
Compass0.Localization.XMLResourceManager.Create(typeof(ucViewHome), ref resources); //created by my code serializier
//
// btnLogin
//
等等
但设计师正在做的是
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ucHome));
this.btnLogin = new ComponentFactory.Krypton.Toolkit.KryptonButton();
this.localizationResourceManager1 = new Compass0.Localization.LocalizationResourceManager(this.components);
//Other designer code to create controls (this is all in the first block of code in InitializeComponent
//
// btnLogin
//
this. btnLogin.Name = "btnLogin";
this. btnLogin.Text = resources.GetString("btnLogin.Text");
Compass0.Localization.XMLResourceManager.Create(typeof(ucViewHome), ref resources); //created by my code serializier
我基本上需要强制设计者在资源初始化后将代码放在第三行。有没有一种方法可以让我直接做到这一点?下面是我的代码生成类
public override object Deserialize( IDesignerSerializationManager manager, object codeDomObject )
{
CodeDomSerializer baseSerializer = ( CodeDomSerializer )manager.GetSerializer( typeof( LocalizationResourceManager ).BaseType, typeof( CodeDomSerializer ) );
return baseSerializer.Deserialize( manager, codeDomObject );
}
public override object Serialize( IDesignerSerializationManager manager, object value )
{
CodeDomSerializer baseSerializer = ( CodeDomSerializer )manager.GetSerializer( typeof( LocalizationResourceManager ).
BaseType, typeof( CodeDomSerializer ) );
object codeObject = baseSerializer.Serialize( manager, value );
if ( codeObject is CodeStatementCollection )
{
CodeStatementCollection statements = ( CodeStatementCollection )codeObject;
CodeTypeDeclaration classTypeDeclaration = ( CodeTypeDeclaration )manager.GetService(typeof( CodeTypeDeclaration ) );
CodeExpression typeofExpression = new CodeTypeOfExpression( classTypeDeclaration.Name );
CodeDirectionExpression resourceRef = new CodeDirectionExpression( FieldDirection.Ref, new CodeVariableReferenceExpression( "resources" ) );
CodeExpression ResourceManagerAssignment = new CodeMethodInvokeExpression(
new CodeTypeReferenceExpression( typeof(XMLResourceManager).ToString() ),
"Create", new CodeExpression[] { typeofExpression, resourceRef } );
statements.Insert( 0, new CodeExpressionStatement( ResourceManagerAssignment ) );
}
return codeObject;
}
我知道这真的很晚了,但是对于任何一个偶然发现这个问题的人 我也在做同样的事情,为了解决这个问题,我只需创建一个类,该类继承自ComponentDesigner,并使用一个Initialize方法获取控件列表,移除自身并将自身重新添加到列表顶部,从而确保首先创建/序列化本地化控件。然后将Designer属性添加到自定义组件中 它是用VB编写的,如果有人需要翻译成C#请告诉我
<Designer(GetType(LocalizerDesigner))>
<DesignerSerializer(GetType(LocalizerSerializer), GetType(CodeDomSerializer))>
Public Class Localizer
Inherits Component
Public Sub GetResourceManager(type As Type, ByRef manager As ComponentResourceManager)
' Replace resource manager w/ new one.
End Sub
End Class
Public Class LocalizerSerializer
Inherits CodeDomSerializer
Public Overrides Function Deserialize(manager As IDesignerSerializationManager, codeObject As Object) As Object
Dim baseSerializer As CodeDomSerializer = DirectCast(manager.GetSerializer(GetType(Component), GetType(CodeDomSerializer)), CodeDomSerializer)
Return baseSerializer.Deserialize(manager, codeObject)
End Function
Public Overrides Function Serialize(manager As IDesignerSerializationManager, value As Object) As Object
Dim baseSerializer As CodeDomSerializer = DirectCast(manager.GetSerializer(GetType(Component), GetType(CodeDomSerializer)), CodeDomSerializer)
Dim codeObject As Object = baseSerializer.Serialize(manager, value)
Dim statementCollection As CodeStatementCollection = TryCast(codeObject, CodeStatementCollection)
If statementCollection IsNot Nothing Then
Dim formClassTypeDeclaration As CodeTypeDeclaration = DirectCast(manager.GetService(GetType(CodeTypeDeclaration)), CodeTypeDeclaration)
Dim typeofFormExpression As New CodeTypeOfExpression(formClassTypeDeclaration.Name)
Dim outResourcesExpression As New CodeDirectionExpression(FieldDirection.Out, New CodeVariableReferenceExpression("resources"))
Dim getResourceManagerExpression As New CodeMethodInvokeExpression(MyBase.SerializeToExpression(manager, value), "GetResourceManager",
{typeofFormExpression, outResourcesExpression})
statementCollection.Add(New CodeExpressionStatement(getResourceManagerExpression))
End If
Return codeObject
End Function
End Class
Public Class LocalizerDesigner
Inherits ComponentDesigner
Public Overrides Sub Initialize(component As IComponent)
MyBase.Initialize(component)
Dim designerHost As IDesignerHost = TryCast(GetService(GetType(IDesignerHost)), IDesignerHost)
If designerHost Is Nothing Then
Return
End If
Dim innerListProperty As Reflection.PropertyInfo = designerHost.Container.Components.GetType().GetProperty("InnerList", System.Reflection.BindingFlags.Instance Or System.Reflection.BindingFlags.NonPublic Or System.Reflection.BindingFlags.FlattenHierarchy)
Dim innerList As ArrayList = TryCast(innerListProperty.GetValue(designerHost.Container.Components, Nothing), ArrayList)
If innerList Is Nothing OrElse innerList.IndexOf(component) <= 1 Then
Return
End If
innerList.Remove(component)
innerList.Insert(0, component)
End Sub
End Class
公共类定位器
继承组件
公共子GetResourceManager(类型为type,ByRef manager为ComponentResourceManager)
'使用新的资源管理器替换资源管理器。
端接头
末级
公共类本地化序列化程序
继承CodeDomSerializer
Public Overrides函数反序列化为对象(manager作为IDesignerSerializationManager,codeObject作为Object)
Dim baseSerializer作为CodeDomSerializer=DirectCast(manager.GetSerializer(GetType(组件)、GetType(CodeDomSerializer))、CodeDomSerializer)
返回baseSerializer.Deserialize(管理器,codeObject)
端函数
公共重写函数序列化(管理器作为IDesignerSerializationManager,值作为对象)作为对象
Dim baseSerializer作为CodeDomSerializer=DirectCast(manager.GetSerializer(GetType(组件)、GetType(CodeDomSerializer))、CodeDomSerializer)
Dim codeObject As Object=baseSerializer.Serialize(管理器,值)
Dim statementCollection作为CodeStatementCollection=TryCast(codeObject,CodeStatementCollection)
如果statementCollection不是空的,那么
Dim formClassTypeDeclaration作为CodeTypeDeclaration=DirectCast(manager.GetService(GetType(CodeTypeDeclaration)),CodeTypeDeclaration)
Dim typeofFormExpression作为新的CodeTypeOfExpression(formClassTypeDeclaration.Name)
Dim OutResourcesPression作为新的CodeDirectionExpression(FieldDirection.Out,新的CodeVariableReferenceExpression(“资源”))
将GetResourceManagerPression设置为新的CodeMethodInvokeeExpression(MyBase.SerializeToExpression(manager,value),“GetResourceManager”,
{typeofFormExpression,outResourcesExpression})
statementCollection.Add(新代码表达式语句(getResourceManagerExpression))
如果结束
返回代码对象
端函数
末级
公共类本地化设计器
继承ComponentDesigner
公共覆盖子初始化(组件作为IComponent)
MyBase.Initialize(组件)
Dim designerHost As IDesignerHost=TryCast(GetService(GetType(IDesignerHost)),IDesignerHost)
如果designerHost不算什么,那么
返回
如果结束
将innerListProperty设置为Reflection.PropertyInfo=designerHost.Container.Components.GetType().GetProperty(“InnerList”、System.Reflection.BindingFlags.Instance或System.Reflection.BindingFlags.NoPublic或System.Reflection.BindingFlags.Flatterhierarchy)
Dim innerList As ArrayList=TryCast(innerListProperty.GetValue(designerHost.Container.Components,Nothing),ArrayList)
如果innerList为Nothing或Else innerList.IndexOf(组件)