2012-04-19 65 views
3

我已经创建了一个组件来为我们的项目进行本地化。我遇到的问题是我输出的代码被注入到InitializeComponent中发生得太晚了。CodeDomSerializer输出订购

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; 
    } 

回答

3

我知道这是真的晚了,但任何人谁在这个问题绊倒......

我在做同样的事情,解决问题我只是确保创建我的定位控制/序列化首先创建一个继承自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