gpt4 book ai didi

c# - CodeDomSerializer 输出顺序

转载 作者:行者123 更新时间:2023-11-30 16:25:07 27 4
gpt4 key购买 nike

我创建了一个组件来为我们的项目做一些本地化工作。我遇到的问题是我输出的注入(inject)到 InitializeComponent 中的代码发生得太晚了。

例子

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

我基本上需要强制设计人员在资源初始化后将我的代码放在第 3 行。有没有办法可以直接做到这一点?我的代码生成类如下。

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

关于c# - CodeDomSerializer 输出顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10237489/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com