UserControl-Sammlung nicht als serialisierbar markiert
Ich muss fehlt etwas wirklich offensichtlich. Ich bin ganz neu bei C# haben aber in der Programmierung in C/C++ für Jahre, also sorry, wenn es etwas offensichtlichen 😉
[Siehe Edit für neuere Probleme]
Ich versuche zum erstellen einer node mit UserControl. Ich habe die Control erscheint in der Windows forms-designer und ich kann Knoten hinzufügen, um es. Aber wenn ich versuche und ausführen des Codes bekomme ich folgende Fehlermeldung:
Code-Generierung für die Eigenschaft 'Knoten' ist fehlgeschlagen. Fehler war: 'Geben Sie
App.Knoten' in Assembly ' - App, version=1.0.0.0, Culture=neutral,
PublicKeyToken=null " ist nicht als serialisierbar markiert.
dann keiner der Knoten I addiert sich zu zeigen.
Dies ist zu Beginn auf drive me mad as, soweit ich sehen kann, IST es als serialisierbar markiert.
Der Knoten ist wie folgt definiert:
[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; }
};
Ich dann definieren Sie eine "Sammlung" wie folgt:
[Serializable]
public class NodeCollection : List< Node >
{
public NodeCollection() :
base()
{
}
};
Sowohl die Sammlung und den Knoten selbst haben das "Serializable" - Attribut gesetzt, wie Sie sehen können.
Knoten erwähnte Eigenschaft, die in der Fehlermeldung ist wie folgt definiert
private NodeCollection mNodes = new NodeCollection();
[Category( "Behavior" )]
[Description( "Nodes" )]
public NodeCollection Nodes
{
get
{
return mNodes;
}
}
Also hat jemand eine Idee, was mache ich hier falsch?
Edit: In Reaktion auf Archeg Kommentare dies ist mein UserControl:
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; }
}
Habe ich einige Modifikationen, da ich ursprünglich gepostet in der Regel in Bezug auf die "DesignerSerializationVisibility" Attribut, das hat geholfen, aber ich bin jetzt immer der folgende build-Fehler:
Fehler MSB3103: Ungültige Resx-Datei. Konnte nicht geladen Typ-App.Knoten, App,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=null die in
die .RESX-Datei. Sicherstellen, dass die erforderlichen Referenzen wurden Hinzugefügt
zu Ihrem Projekt.
Edit 2: es ist erwähnenswert, dass meine Probleme nur auftreten, wenn ich das hinzufügen von ein paar Knoten in die designer dann bekomme ich den oben Resx Fehler. Wenn ich die Knoten manuell aus dem code dann funktioniert alles wie ich es erwarten würde ...
- Welche Steuerung verwendest du? Ist es Gewohnheit?
- Yup seiner komplett eigenen direkt abgeleitet von UserControl
- Können Sie Ihre post-code UserControl?
- Code Hinzugefügt und aktualisiert leicht mit meinen neuesten Themen ...
Du musst angemeldet sein, um einen Kommentar abzugeben.
Ich glaube, dass Sie dieses problem haben, da der Designer versucht automatisch serialisiert alle öffentlichen UserControl-Eigenschaften. Wenn diese Eigenschaft ist nicht notwendig für Ihre benutzerdefinierte UserControl-design-Zeit-Unterstützung, dann können Sie "DesignerSerializationVisibility" Attribut:
oder einfach weglassen, die
get{}
undset{}
Methoden der Eigenschaft und verwenden Sie es als ein öffentliches Feld.Hoffe, es hilft!
Dass ist sehr seltsam. Ich habe es kopiert, lokal auf meinen Hinweis, dann zog Knoten-Klasse in ein anderes Projekt und es hat funktioniert. Ich denke, es ist etwas mit zyklischen Abhängigkeiten - es versucht zu finden, Ihre Montage (in meinem Fall war es WindowsFormsApplication1) gebaut, aber es kann nicht, wie es ist, bauen Sie es jetzt.
Hoffe, dass Sie helfen, und ich werde versuchen, weiter zu Graben.
Update
Ein anderer Weg, um es zu lösen: entfernen Sie [Serialization] - Attribut von der Knoten-Klasse. In diesem Fall werden Sie zwingen, VS anstelle der Generierung von Node-Inhalt in der resx-Datei, generieren Sie einfach diesen code: