Entwickler-Ecke

WinForms - Eigenschaften zu allen Controls hinzufügen


DoTa - Do 25.06.09 11:54
Titel: Eigenschaften zu allen Controls hinzufügen
Ich sitze gerade an meiner Vertieferarbeit und habe die Aufgabe eine Sprachsteuerung zu integrieren bzw. zu erstellen.

Um die Controls anzusteuern, brauchen diese bestimmte Eigenschaften, wie z.B. "Ansprechname", "Zugangseigenschaft".. (wen es interessiert, dem erläutere ich es gern ausführlicher).

Meine Idee war es zunächst, diese über eine Datenbank abzurufen und zu speichern, jedoch bin ich mittlerweile davon abgekommen, da ich keine Schleife über alle Formulare bilden kann.

Also dachte ich mir, wie auch zu Beginn der Arbeit, setzen wir doch einfach eigene Eigenschaften in die Controls. Da ich aber auf ein bestehendes Programm aufbaue, hatte ich keine Lust alle Controls durch meine CustomControls zu ersetzen.

Nun aber zu meiner eigentlichen Frage:

Kann man die System.Windows.Form.Control um ein paar Eigenschaften ergänzen? Da ja alle Controls (ob Textbox oder Checkbox) von dieser Klasse erben.

Oder habt ihr andere Lösungsvorschläge?


JüTho - Do 25.06.09 12:38

Hallo und :welcome:

user profile iconDoTa hat folgendes geschrieben Zum zitierten Posting springen:
Kann man die System.Windows.Form.Control um ein paar Eigenschaften ergänzen? Da ja alle Controls (ob Textbox oder Checkbox) von dieser Klasse erben.

Eigentlich wäre das nichts anderes als CustomControl; aber das hilft dir natürlich nichts (wie dir offensichtlich bewusst ist), weil TextBox usw. von Control abgeleitet ist und nicht von CustomControl.

Da du mit 3.5 arbeitest, könnten die Erweiterungsmethoden (Extensions) helfen; aber ich arbeite noch nicht damit, habe also keine Ahnung.

Übrigens gibt es Control.Tag-Eigenschaft, über die du beliebige Objekte anhängen kannst, z.B. auch eine Dictionary<key, value>. Vielleicht hilft das am schnellsten weiter.

Gruß Jürgen


Christian S. - Do 25.06.09 12:41

user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Da du mit 3.5 arbeitest, könnten die Erweiterungsmethoden (Extensions) helfen; aber ich arbeite noch nicht damit, habe also keine Ahnung.

Extension Methods sind einfach nur statische Methoden mit ein bisschen netterer Syntax, damit kann man also keine Eigenschaften zu "fertigen" Klassen hinzufügen.


Ralf Jansen - Do 25.06.09 12:49

Dafür bietet sich ein ExtenderProvider an. Die werden z.B. vom Framework auch für die Lokalisierung, ErrorProvidern oder bei Tooltips verwendet um Controls um Properties zu ergänzen.

Guckst du z.B. hier [http://msdn.microsoft.com/de-de/library/d6c1xa43.aspx].


DoTa - Do 25.06.09 14:54

Danke zunächst an alle!!!

user profile iconJüTho hat folgendes geschrieben Zum zitierten Posting springen:
Hallo und :welcome:

Eigentlich wäre das nichts anderes als CustomControl; aber das hilft dir natürlich nichts (wie dir offensichtlich bewusst ist), weil TextBox usw. von Control abgeleitet ist und nicht von CustomControl.


Dachte eher daran, eine eigene System.Forms.dll zu erstellen, in der Hoffnung, dass dort alle verwendeten Properties beschrieben sind. D.h. ich hätte nur den Verweis auf die (System.Forms.dll) auf meine Eigene verändern müssen.

Werde mich erstmal mit den Extensions auseinander setzen...

Gib dann später Bescheid, ob es funktioniert hat.


DoTa - Do 25.06.09 19:47

user profile iconDoTa hat folgendes geschrieben Zum zitierten Posting springen:


Gib dann später Bescheid, ob es funktioniert hat.




Es hat leider nicht nicht mit dem ExtenderProvider funktioniert. Hat jmd. vielleicht noch andere Beispiele zu diesem Thema, hört sich nämlich interessant an.

Ansonsten bleibt Frage weiterhin bestehen, kann man ein oder mehrere Eigenschaften nachträglich zu allen Controls hinzufügen? Am liebsten wäre mir, wenn man diese dann auch über die Eigenschaften im Visual-Studio verändern kann.

Danke im vorraus.


Ralf Jansen - Do 25.06.09 19:47

DoTA hatte per PN nach einem Beispiel bezüglich ExtenderProvider gefragt.
@Dota : demnächst Bitte keine Fragen mehr via PN (zumindest nicht an mich). Das Forum selbst ist dafür geeigneter.

Im Beispiel eine ExtenderProvider als Component der die Textbox Klasse um eine Property "MeineProperty ergänzt".
Wenn du das Beispiel kompilierst erhälst du eine Componente die du auf eine Form werfen kannst und dann für alle Textboxen der Form die neue Property bekommst.


C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
    [ProvideProperty("MeineProperty"typeof(Control))]  // Name der hinzuzufügenden Property und Typ der zu erweiternden Klassen
    public partial class TextBoxExtender : Component, IExtenderProvider
    {
        private Hashtable meineProperties = new Hashtable(); // da wir mehrere Controls erweitern müssen wir irgendwo die Property Werte je Control ablegen
          
        public TextBoxExtender()
        {
        }

        public TextBoxExtender(IContainer container)
        {
            container.Add(this);
        } 

        public bool CanExtend(object extendee)
        {
            return (extendee is TextBox); // Wir wollen nur Textboxen erweitern.
        }

        public string GetMeineProperty(Control control) // Getter der neuen Property (man beachtete das Get+PropertyNamen)
        {
            if ((meineProperties.Contains(control) &&
                (meineProperties[control] != null)))
                return (string)meineProperties[control];
            return "";
        }

        public void SetMeineProperty(Control control, string value) // Setter der neuen Property (man beachtete das Set+PropertyNamen)
        {
            meineProperties[control] = value;
        }

    }


DoTa - Do 25.06.09 20:21

Also dein Beispiel ist fehlerlos, jedoch, kriege ich keine neue Eigenschaft bei der Textbox angzeigt. In deinem Beispiel müsste dann ja "MeineProperty" als Eigenschaft zu sehen sein. Kann es daran liegen, dass ich hier zu Hause mit VS 2005 und .NET 2.0 arbeite?


Ralf Jansen - Do 25.06.09 20:27

Die neue Property heißt an den Textboxen dann "MeineProperty on NameDesTextBoxExtenders". Das Aufnehmen des Namens der Extenderklasse muß sein da man ja mehrere Extender auf die Form werfen könnte die die gleichen Propertynamen liefern.

Ich selbst habs mit VS2008 probiert da funktioniert das Wunderbar. Sollte unter VS2005 aber genauso gehen und habe das auch dort schon(nicht mit diesem Beispiel) so gemacht. :gruebel: Du hast nicht zufällig versucht die Property umzubennen und vergessen die Namen des Getters und Setters nachzuziehen?


DoTa - Do 25.06.09 20:43

user profile iconRalf Jansen hat folgendes geschrieben Zum zitierten Posting springen:
Die neue Property heißt an den Textboxen dann "MeineProperty on NameDesTextBoxExtenders". Das Aufnehmen des Namens der Extenderklasse muß sein da man ja mehrere Extender auf die Form werfen könnte die die gleichen Propertynamen liefern.

Ich selbst habs mit VS2008 probiert da funktioniert das Wunderbar. Sollte unter VS2005 aber genauso gehen und habe das auch dort schon(nicht mit diesem Beispiel) so gemacht. :gruebel: Du hast nicht zufällig versucht die Property umzubennen und vergessen die Namen des Getters und Setters nachzuziehen?


Habs jetzt auch... habe es mit

C#-Quelltext
1:
2:
3:
4:
 public TextBoxExtender()
        {
            InitializeComponent();
        }

erweitert. Und es hat geklappt.

Nur habe ich das Problem, dass der TextBoxExtender nach dem Kompilieren aus meiner Form wieder verschwindet. Hast du da eine Idee wie man den dauerhaft einstellt?


Ralf Jansen - Do 25.06.09 20:59

Du hast wahrscheinlich in VS eine neue Komponente angelegt und den Beispiel Code reinkopiert. Dann erhälst du auch eine *.Designer.cs Datei mit einer InitializeComponent Methode. Der Extender hat aber selbst keine designbare Oberflache. InitializeComponent ist also nicht notwendig. Ich würde die Designer.cs löschen und InitializeComponent wieder rauswerfen.

Das der nach dem Kompilieren verschiedet kann ich mir nicht erklären. Da gibt es eigentlich auch nichts einzustellen.
Kontrollier mal die Designer.cs Datei vor und nach dem kompilieren. Ist der Member für den Extender vorhanden? Ist der Code zum erzeugen des Extender in der InitializeComponent noch vorhanden nach dem kompilieren?


DoTa - Do 25.06.09 21:31

Da war wohl irgendetwas zerschossen.

Hat nun wunderbar funktioniert. Ein riesengroßes Dankeschön an Dich und natürlich an alle anderen.

Werde den Extender verwenden. Vll. benutze ich statt einem Hashtable eine DB, aber im großen und ganzen bin sehr zufrieden, dass es nun weitergehen kann.