2009-11-13 13 views
2

J'utilise .NET C# avec WinForms standard, pas WPF.C# afficher les propriétés enfant navigables dans le concepteur

J'ai cette situation. Je crée un contrôle utilisateur pour un calendrier mensuel, similaire au .NET mais avec un peu plus de fonctionnalités. J'ai un formulaire de contrôle d'utilisateur, qui remplit avec des objets de bouton représentant des dates. Les boutons peuvent être colorés avec des couleurs différentes en fonction de leur état (sélectionné, souris, week-end ...)

La façon dont je voudrais que cela fonctionne est d'étendre la classe de bouton pour accepter les états, qui déterminent les couleurs, plutôt que de les colorer à partir de la classe parent (contrôle utilisateur). Il y a 10 couleurs en ce moment et je ne voudrais vraiment pas gâcher le code de contrôle de l'utilisateur avec des conditions de coloration.

Aussi, je voudrais sélectionner toutes les couleurs au moment du design, en utilisant les propriétés de designer navigables. Le problème est que le concepteur montre uniquement les propriétés définies dans la classe de contrôle utilisateur, et non ses enfants (boutons).

Y a-t-il une solution de contournement pour ce problème? Donc, pour faire court, je veux changer les couleurs en utilisant les propriétés des boutons internes, et pouvoir les sélectionner au moment du design, en utilisant les propriétés du concepteur, et non les coder manuellement.

+0

Certains exemples de code de l'apparence de vos classes enfant aideraient – thecoop

+0

L'enfant est une classe simple qui étend la classe Button. Il a différents constructeurs en fonction de la taille, du texte et de l'emplacement. Id comme toutes les couleurs à être des propriétés de cette classe. Mais je voudrais les sélectionner dans la fenêtre des propriétés du concepteur du contrôle utilisateur (parent) lorsque je fais glisser le contrôle utilisateur vers un cadre. –

+0

Exemple ajouté; est-ce que des millions de kilomètres? –

Répondre

1

Il y a plusieurs choses que vous pouvez faire ici - vous pourriez (bien que ce soit une mauvaise réponse) exposer les contrôles en question sur l'interface publique - mais je ne suis pas sûr que ce soit une bonne idée.

Personnellement, je voudrais juste réexposer les propriétés qui m'intéressent, peut-être les mettre dans un autre [Category(...)] - en veillant à avoir à la fois des setters et des getters.

Un peu comme:

using System; 
using System.ComponentModel; 
using System.Drawing; 
using System.Windows.Forms; 

class MyControl : UserControl 
{ 
    private Button button; 
    private Label label; 
    public MyControl() 
    { 
     button = new Button { Dock = DockStyle.Right, Text = "Click me" }; 
     label = new Label { Dock = DockStyle.Left}; 
     Controls.Add(button); 
     Controls.Add(label); 
    } 
    [Category("Wonder Control")] 
    public string CaptionText { get { return label.Text; } set { label.Text = value; } } 
    [Category("Wonder Control")] 
    public Color ButtonBackColor { get { return button.BackColor; } set { button.BackColor = value; } } 
} 
static class Program 
{ 

    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 

     using (Form form = new Form()) 
     using (MyControl ctrl = new MyControl()) 
     using (PropertyGrid grid = new PropertyGrid()) 
     { 
      ctrl.ButtonBackColor = Color.Red; 
      ctrl.CaptionText = "Caption"; 
      ctrl.Dock = DockStyle.Fill; 
      grid.Dock = DockStyle.Right; 
      form.Controls.Add(ctrl); 
      form.Controls.Add(grid); 
      grid.SelectedObject = ctrl; 
      Application.Run(form); 
     } 

    } 
} 
+0

Comment voulez-vous dire re-exposer? Je peux les exposer dans la classe parent avec [Category]. Existe-t-il un moyen de les exposer uniquement en classe enfant? –

2

Pour une propriété d'être visible dans le concepteur, ils doivent être des propriétés publiques avec un getter et setter - de ce que vous dites, les propriétés ne sont que getters. Vous pouvez également essayer de préciser BrowsableAttribute et BindableAttribute sur les propriétés de contraindre le concepteur pour les afficher ...

3

Ok, je vais essayer d'expliquer le code de creux:

Par exemple, j'ai un contrôle utilisateur et un classe de bouton. Je souhaite exposer les propriétés du bouton et les rendre visibles dans les propriétés MyControl du concepteur.

class MyControl : UserControl 
{ 
    private MyButton button; 
    button.ChangeStyle("Selected"); 
} 

class MyButton : Button 
{ 
    private Color buttonColor; 

    public void ChangeStyle(string styleName) 
    { 
      if (styleName == "Selected") 
       this.BackColor = buttonColor; 
    } 

    [Browsable(true)] 
    [Category("Button style")] 
    public Color ButtonColor 
    { 
      get { return buttonColor; } 
      set { buttonColor = value; } 
    } 
} 

Ceci est un exemple simple. Normalement, j'ai 5 styles différents, y compris la couleur de fond et de premier plan pour chacun d'eux. Donc, au lieu de gérer les couleurs dans la classe MyControl, j'aimerais les définir dans la classe MyButton. Mais le problème est que les propriétés de la classe MyButton ne sont pas visibles dans le concepteur, car elles se concentrent uniquement sur les propriétés MyControl.

Btw. ignorer les constructeurs manquants et d'autres choses classes de base dans l'exemple de code

Je ne peux pas utiliser:

[Category("Wonder Control")] 
public Color ButtonBackColor { get { return button.BackColor; } set { button.BackColor = value; } 

parce que j'ai 30 boutons MyControl (jours dans le mois), et je ne peux pas faire référence à tout un seul objet.

0

Si tous les boutons du contrôle partagent la même apparence, pourquoi ne pas placer la propriété au niveau du contrôle et demander à l'éditeur de propriétés de modifier tous les boutons? En outre, l'utilisation de 30 contrôles de boutons individuels semble beaucoup de frais généraux ... avez-vous envisagé de dessiner les étiquettes pour les jours et de gérer les événements clic/hover de la souris pour déterminer quand un jour particulier est cliqué?

+0

C'est la solution actuelle. J'ai des propriétés de contrôle pour les couleurs et les propage aux boutons. J'ai envisagé de tout dessiner manuellement, mais je veux que les boutons soient des objets actifs, pas seulement des graphiques simples. Je voudrais éviter de tester l'ensemble du contrôle utilisateur pour déterminer la date sélectionnée. De cette manière, je n'ai pas besoin de redessiner toutes les dates à chaque clic, seulement celles qui ont été changées. –

+0

Qu'entendez-vous par "beaucoup de frais généraux"? Problèmes de performance ou juste beaucoup de code inutile? Je pensais à créer manuellement la classe de boutons, pas seulement hériter de Button et mettre en œuvre uniquement les fonctionnalités dont j'ai besoin –