ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C#-CodeDomSerializer输出顺序

2019-12-01 12:18:11  阅读:179  来源: 互联网

标签:custom-controls c designer


我创建了一个组件来为我们的项目做一些本地化工作.我遇到的问题是,输出到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

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

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

标签:custom-controls,c,designer
来源: https://codeday.me/bug/20191201/2080845.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有