2012-03-20 41 views
7

我必須缺少真正明顯的東西。我很新的C#,但在C/C++已編程多年,很抱歉,如果這是值得言自明;)未標記爲可序列化的UserControl集合

[較新的問題,請參見編輯]

我想創建一個包含UserControl的節點。我有WinForm設計器中出現的控件,我可以添加節點。但是,當我嘗試運行代碼時,出現以下錯誤:

Code generation for property 'Nodes' failed. Error was: 'Type App.Node' in Assembly 'App, version=1.0.0.0, Culture=neutral, PublicKeyToken=null' is not marked as serializable.

然後沒有添加的節點出現。

這讓我很生氣,就我所知,它被標記爲可序列化。

的節點被定義爲如下:

[Serializable] 
public class Node : MarshalByRefObject 
{ 
    public Node() 
    { 
    } 

    public Node(String text) 
    { 
     this.Text  = text; 
     this.Checked = false; 
     this.Complete = false; 
    } 

    public String  Text  { get; set; } 
    public bool   Checked  { get; set; } 
    public bool   Complete { get; set; } 
    public bool   Selected { get; set; } 
}; 

我然後定義一個「集合」,如下所示:

[Serializable] 
public class NodeCollection : List<Node> 
{ 
    public NodeCollection() : 
     base() 
    { 
    } 
}; 

兩個集合和節點本身具有「序列化」屬性設置爲你可以看到。

中提到的錯誤

節點屬性定義爲如下

private NodeCollection  mNodes = new NodeCollection(); 

    [Category("Behavior")] 
    [Description("Nodes")] 
    public NodeCollection Nodes 
    { 
     get 
     { 
      return mNodes; 
     } 
    } 

所以有沒有人有任何想法什麼我做錯了嗎?

編輯:針對Archeg的意見,這是我的用戶:

public partial class Control : UserControl 
{ 
    public Control() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnPaint(PaintEventArgs pe) 
    { 
     Graphics graph = pe.Graphics; 

     int rowHeight = Font.Height + 2; 

     if (Nodes != null) 
     { 
      int yPos = 0; 
      foreach(Node node in this.Nodes) 
      { 
       // Calculate my various bounding boxes. 
       Rectangle nodeBounds = new Rectangle(Bounds.Left, yPos, Bounds.Width, rowHeight); 
       Rectangle lightBounds = new Rectangle(Bounds.Right - Font.Height, yPos, rowHeight, rowHeight); 
       Rectangle spannerBounds = new Rectangle(lightBounds.Left - Font.Height, yPos, rowHeight, rowHeight); 
       Rectangle checkBoxBound = new Rectangle(32, yPos, rowHeight, rowHeight); 
       Rectangle textBounds = new Rectangle(checkBoxBound.Right, yPos, Bounds.Width - (rowHeight * 2) - checkBoxBound.Right, rowHeight); 

       // Draw selection box. 
       Brush textColour = Brushes.Black; 
       if (node.Selected) 
       { 
        graph.FillRectangle(Brushes.Blue, nodeBounds); 
        textColour  = Brushes.Yellow; 
       } 

       // Draw node text. 
       graph.DrawString(node.Text, Font, textColour, textBounds); 

       // Draw Red/Green light 
       Image[] lightImages = new Image[] { CompleteLightImage, InCompleteLightImage }; 
       Image lightImage = lightImages[node.Complete ? 1 : 0]; 
       if (lightImage != null) 
       { 
        graph.DrawImage(lightImage, lightBounds); 
       } 

       // Draw Spanner Icon 
       if (SettingsImage != null) 
       { 
        graph.DrawImage(SettingsImage, spannerBounds); 
       } 
       // Draw check box. 
       VisualStyleRenderer renderer = null; 
       VisualStyleElement ve   = node.Checked ? VisualStyleElement.Button.CheckBox.CheckedPressed : VisualStyleElement.Button.CheckBox.CheckedNormal; 
       if (VisualStyleRenderer.IsElementDefined(ve)) 
       { 
        renderer = new VisualStyleRenderer(ve); 
       } 

       if (renderer != null) 
       { 
        renderer.DrawBackground(graph, checkBoxBound); 
       } 
       else 
       { 
        ControlPaint.DrawCheckBox(graph, checkBoxBound, node.Checked ? ButtonState.Checked : ButtonState.Normal); 
       } 
       yPos += Font.Height; 
      } 
     } 
    } 

    private NodeCollection  mNodes = new NodeCollection(); 

    [Category("Behavior")] 
    [Description("Nodes")] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    [MergableProperty(false)] 
    [Bindable(false)] 
    public NodeCollection Nodes 
    { 
     get 
     { 
      return mNodes; 
     } 
    } 

    public Image CompleteLightImage   { get; set; } 
    public Image InCompleteLightImage  { get; set; } 
    public Image SettingsImage    { get; set; } 
} 

我已經做了一些修改,因爲我原來一般張貼有關「DesignerSerializationVisibility」屬性,它已幫助,但現在我得到下面的生成錯誤:

error MSB3103: Invalid Resx file. Could not load type App.Node, App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null which is used in the .RESX file. Ensure that the necessary references have been added to your project.

編輯2:它值得一提的是,當我加了一堆N個我的問題只發生在設計師的頌歌,然後我得到以上Resx錯誤。如果我從代碼手動添加節點,那麼它一切正常,我所期望的...

+0

你使用什麼控制?它是自定義的嗎? – Archeg 2012-03-20 15:13:51

+0

@Archeg:是完全自定義直接從UserControl派生的 – Goz 2012-03-20 15:15:32

+0

你可以發佈你的UserControl代碼嗎? – Archeg 2012-03-20 15:18:06

回答

18

我相信你有這個問題,因爲設計器會自動嘗試序列的所有公共用戶控件的屬性。如果不需要爲您的自定義用戶控件的設計時支持此屬性,那麼你可以加入「DesignerSerializationVisibility」屬性:

[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)] 

或者乾脆省略財產get{}set{}方法和使用它作爲一個公共領域。

希望它能幫助!

+1

它是正確的解決方案。你救了我。 – 2017-01-05 14:35:49

2

這很奇怪。我在筆記本地複製了它,然後將Node類移到了另一個項目中,並且工作正常。我認爲這是循環依賴的東西 - 它試圖找到你的程序集(在我的情況下是WindowsFormsApplication1),但它不能像它現在正在構建它。

希望對你有幫助,我會盡力進一步挖掘。

更新 另一種解決方法:從Node類中刪除[Serialization]屬性。在這種情況下,你將迫使VS而不是RESX文件生成節點內容,只是產生這樣的代碼:

// Form1.designer.cs: 
Node node1 = new Node(); 
node1.Checked = false; 
node1.Complete = false; 
node1.Selected = false; 
node1.Text = null; 
this.contr1.Nodes.Add(node1); 
+0

添加了另一個解決方案 – Archeg 2012-03-20 16:14:12

+0

在底部添加了一個額外的編輯。基本上問題在於設計師出了什麼問題......不知道這是否對你有所幫助 – Goz 2012-03-20 16:16:26

+0

是的,似乎VS未能在它正在構建的控制器上生成序列化數據。你是否介意我把它當作微軟的一個bug發佈,因爲我沒能找到一些有意義的解釋? – Archeg 2012-03-20 16:25:56

相關問題