2

Je crée un contrôle personnalisé qui prendra forme à partir d'une liste (ou tableau) de points. J'ai des fonctionnalités de dessin de base, mais maintenant je suis aux prises avec un support au moment du design dans Visual Studio.Impossible de modifier le point [] ou la liste <Point> au moment du design

J'ai créé deux propriétés:

private Point _point; 
public Point Point 
{ 
    get { return _point; } 
    set { _point = value; } 
} 

private Point[] _points; 
public Point[] Points 
{ 
    get { return _points; } 
    set { _points = value; } 
} 

Comme on le voit sur l'écran ci-dessous Point est modifiable, mais éditeur pour Points ne fonctionne pas. Pour chaque propriété, j'obtiens l'erreur Object does not match target type.

enter image description here

Si je change Point à MyPoint (classe personnalisée avec X, propriétés Y) éditeur fonctionne très bien, mais je ne veux pas créer non nécessaire classe supplémentaire parce que l'éditeur ne ne fonctionne pas quand il le faut.

Ma question est la suivante: Puis-je utiliser un tableau ou une liste de points en tant que propriété publique et en avoir le support au moment du design?

+0

Le problème est peut-être l'éditeur de collection prêtant à confusion 'point' pour 'pointf' http://stackoverflow.com/questions/2597737/collectionedi tor-yielding-object-does-not-match-cible-type-pour-system-drawin –

+0

@TimothyGroote merci pour le lien – Misiu

Répondre

1

Vous pouvez créer un éditeur de collection personnalisée provenant CollectionEditor et définir typeof(List<Point>) comme type de collection, enregistrent également une nouvelle TypeConverterAttribute pour Point:

// Add reference to System.Design 
using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.ComponentModel.Design; 

public class MyPointCollectionEditor : CollectionEditor 
{ 
    public MyPointCollectionEditor() : base(typeof(List<Point>)) { } 
    public override object EditValue(ITypeDescriptorContext context, 
     IServiceProvider provider, object value) 
    { 
     TypeDescriptor.AddAttributes(typeof(Point), 
      new Attribute[] { new TypeConverterAttribute() }); 
     var result = base.EditValue(context, provider, value); 
     TypeDescriptor.AddAttributes(typeof(Point), 
      new Attribute[] { new TypeConverterAttribute(typeof(PointConverter)) }); 
     return result; 
    } 
} 

Ensuite, il suffit de l'enregistrer comme rédacteur en chef de votre List<Point>:

using System.Collections.Generic; 
using System.ComponentModel; 
using System.Drawing; 
using System.Drawing.Design; 

public class MyClass : Component 
{ 
    public MyClass() { Points = new List<Point>(); } 

    [Editor(typeof(MyPointCollectionEditor), typeof(UITypeEditor))] 
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)] 
    public List<Point> Points { get; private set; } 
} 
+0

Merci. Cela fonctionne bien. J'ai un problème avec le fichier 'Designer.cs'. Après avoir ajouté des points, ils sont visibles dans 'Designer.cs' sous le nom' this.shape1.Points.Add (((System.Drawing.Point) (resources.GetObject ("shape1.Points")))); 'Puis-je changer cela? , de sorte qu'au lieu de ressources, je vais voir les valeurs dans Designer? Dois-je créer une sorte de convertisseur pour cela? – Misiu

+0

Après avoir fermé la boîte de dialogue (après 'EditValue'), réglez à nouveau le convertisseur sur' PointConverter'. J'ai édité le post. –

+0

Fantastique! Merci pour l'aide. – Misiu

1

Si vous pouvez ajouter une référence à PresentationCore et WindowsBase, vous pouvez utiliser le System.Windows.Media.PointCollection

private System.Windows.Media.PointCollection _points = new System.Windows.Media.PointCollection(); 
public System.Windows.Media.PointCollection Points 
{ 
    get { return _points; } 
    set { _points = value; } 
} 

espoir qui peut aider.

+0

Merci pour la suggestion, je vais laisser cette question ouverte pendant un certain temps. Votre solution est une option, mais nécessite deux dépendances. Je voudrais les garder le moins possible, donc peut-être il y aura une option pour utiliser Point à la place Points mais en utilisant build dans les collections – Misiu

+0

@Misiu, pas de soucis de laisser ouverte, je serais curieux de savoir s'il y a une autre façon n'implique pas non plus une classe personnalisée ou un conteneur personnalisé. Mais par curiosité, quelle version du framework .NET ciblez-vous? 'PresentationCore' et' WindowsBase' font partie du framework .NET depuis la version 3.0, donc ajouter une référence à eux n'est pas ajouter une dépendance comme ajouter une référence au framework 'XNA'. – txtechhelp