none
Benutzersteuerelement: Items einer combobox hinzufügen RRS feed

  • Frage

  • Hallo liebe Community,

    Ich möchte ein Benutzersteuerelement (namens ComboBoxButton) erstellen, welches eine Combobox und einen Button beinhaltet. Ereignisse und einfache Textfeldern kann ich ohne Probleme durchschleusen, also dass ich über das Benutzersteuerelement z.B. auf das Click Ereignis des Buttons reagieren kann.

    Doch komme ich einfach nicht drauf, wie ich das mit den Items machen soll. Gleich an zwei Dingen scheitere ich. Zum einen kann man, wenn man die original Combobox auf seine Form zieht, schön im Eigenschaftenfenster die Items bearbeiten. Dazu geht ein extra Fenster auf, in diesem man pro Zeile ein Item hinzufügen kann. Wie kann ich das mit meinem Benutzersteuerelement machen?

    Desweiteren weiß ich nicht, wie ich es angehen muss, damit ich im Quellcode einer beliebigen Form, auf der mein Benutzersteuerelement gezogen wurde, mit dem Befehl "ComboBoxButton1.items.add("bla")" neue Items hinzufügen kann. Ich würde es wohl hinbekommen eine Methode zu schreiben, mit der ich dann folgendes anstellen könnte: "ComboBoxButton1.AddItem("bla"), aber ich möchte sämtliche Befehle die mit den Items zu tun haben, unter Items zusammengefasst haben.

    Ich habe schon ne Weile gegoogelt, aber dort findet man quasi immer nur die Standard Tutorials für absolute Anfänger (ja, ich weiß, ich bin eigentlich auch nicht besser).

    Hoffe mir kann jemand helfen. :/

     

    Liebe Grüße

    Manuel

     

    ich habe in meinen Büchern leider immer nur rudimentäre Hilfe gefunden, die mir hier nichts bringt.

    Donnerstag, 2. September 2010 15:35

Antworten

Alle Antworten

  • Hallo Manuel

    die wichtigsten (aber ggf nicht alle) Punkte sind wohl:

    Gewusst wie: Verfügbarmachen der Eigenschaften konstituierender Steuerelemente
    http://msdn.microsoft.com/de-de/library/02a1w7dy.aspx

    Designer:
    Editor-Arribute
    http://msdn.microsoft.com/en-us/library/system.componentmodel.editorattribute.aspx

    String Collection Editor
    http://msdn.microsoft.com/en-us/library/42737xf2.aspx

    http://social.msdn.microsoft.com/forums/en-US/winforms/thread/47977ca0-14e9-47ec-9555-8884736f9bde

    (data binding) Exposing property of constituent control
    http://social.msdn.microsoft.com/Forums/en/winformsdesigner/thread/6239f7e6-4a50-4c26-9986-b76a522f2235

    Donnerstag, 2. September 2010 16:30
  • Hallo Manuel,

    um Steuerelemente bzw. deren Eigenschaften in Benutzersteuerelementen verfügbar zu machen, muss es eine Methode oder Property geben, die public ist. Standardmäßig ist ja alles private. Deswegen funktioniert der Zugriff nicht.

    Die quick-and-dirty-Lösung wäre, das Steuerelement selbst im Benutzersteuerelement als public zu deklarieren. Die saubere Lösung ist, die gewünschten Eigenschaften über eigene Properties nach außen zugänglich zu machen. Weiterer Vorteil bei zweiter Vorgehensweise ist, dass Properties dann auch im Eigenschaften-Fenster des Benutzersteuerelements auftauchen.

    Viele Grüße

    Jan

    Donnerstag, 2. September 2010 16:34
  • Hallo Manuel,

    Für die Items-Eigenschaft eines eigenen UserControls mit einer inneren ComboBox nimm zum Beispiel (als Ansatz) :

    public partial class UserControl1 : UserControl
     {
     public UserControl1(){InitializeComponent();}
    
     [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, " +
      "System.Design, Version=4.0.0.0, Culture=neutral, " +
      "PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor))]
     [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
     public ComboBox.ObjectCollection Items 
     {
      get { return comboBox1.Items; }
     }
     }
    

     


    ciao Frank
    Donnerstag, 2. September 2010 20:12
  • Hallo Manuel und Jan,

    Jans Lösung(en) gefallen mir gut, weil sie sehr einfach zu implementieren sind. Die quick-and-dirty-Lösung habe ich schon in vielen professionellen Lösungen gesehen (z.B. bei den DevExpress-Controls). Aber klar, man entscheidet von Fall zu Fall. Manchmal reicht aber auch schon Code wie dieser:

    using System;
    using System.Windows.Forms;
    using System.ComponentModel;
    
    namespace WindowsFormsApplication2
    {
     public partial class UserControl1 : UserControl
     {
      public UserControl1() { InitializeComponent(); }
    
      [DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
      public ComboBox ComboBoxProperties { get { return comboBox1; } }
     }
    }
    
    

    Wichtig dabei ist das DesignerSerializationVisibilityAttribute, ohne das die vorgenommenen Einstellungen nicht dauerhaft serialisiert werden können. Das PropertyGrid bzw. seine Unterklassen (PropertyGridView) sorgen automatisch dafür, dass der richtige Editor für die aktuell selektierte Eigenschaft angezeigt wird.

    Will man statt dem Standard-Editor (StringCollectionEditor) einen anderen Editor anzeigen (z.B. ListControlStringCollectionEditor), dann ist Franks Vorschlag weiter unten gut geeignet (man muss sich natürlich darüber im Klaren sein, dass die meisten Editoren als internal deklariert sind und daher alle Konsequenzen in Erwägung ziehen). In speziellen Fällen kann man auch selber einen Editor von System.ComponentModel.Design.CollectionEditor ableiten, oder noch tiefer in der Hierarchie auf der UITypeEditor-Ebene arbeiten.

    Gruß
    Marcel

    Freitag, 3. September 2010 07:58
    Moderator
  • Danke für die Hilfe Frank,

    wie immer war deine Hilfe genau das was ich brauchte!

    Freitag, 3. September 2010 14:41
  • Danke für die Hilfe. Quick-and-dirty kommt bei mir jedoch nicht in Frage. Ich versuche sauber sämtliche Eigenschaften nach außen zugänglich zu machen. Die Antwort von Frank Dzaebel hat mir dann weiter geholfen.

    Die Lösung ein Control komplett durchzureichen ist zwar nicht in meinem Sinne, aber sollte ich an anderer Stelle, z.B. bei der Datenbindung, nicht weiterkommen, werde ich es zumindest im Hinterkopf haben.

    Freitag, 3. September 2010 14:42
  • Danke, ich werde mir die Seiten alle intensiv anschauen.
    Freitag, 3. September 2010 14:47
  • Hallo Marcel, :-)

    meine Lösung benutzt doch genau den Editor, den die .NET ComboBox für die Items auch benutzt.
    Da kann man hübsch Items pro Zeile eingeben. Es ist eben exakt das, was hier gewünscht wurde :-)


    ciao Frank
    Freitag, 3. September 2010 15:09
  • Genau :)

    Freitag, 3. September 2010 15:30
  • Hallo Frank,

    Du hast Recht. Sorry! Ich hatte übersehen, dass der ListControlStringCollectionEditor von StringCollectionEditor abgeleitet ist. Mein Fehler.

    Gruß
    Marcel

    Freitag, 3. September 2010 15:30
    Moderator
  • Hallo Marcel,

    kein Problem, danke.

    ciao Frank
    Freitag, 3. September 2010 15:40
  • Manuel,

    gut finde ich übrigens auch, dass du offenbar sehr wohl festgestellt hast, dass einer meiner Links
    http://social.msdn.microsoft.com/forums/en-US/winforms/thread/47977ca0-14e9-47ec-9555-8884736f9bde

    bereits alle relevante Codeausschnitte (inkl Attributen) enthielt,
    und dies >4Std bevor die üblichen 'Kopien' nachgereicht wurden.   ;-)
    SCNR
    Freitag, 3. September 2010 18:24
  • Hallo Thomas,

    [...] SCNR

    Ich verstehe Dich nur allzu gut, aber man muss wahrlich nicht social.msdn.microsoft.com konsultieren, um herauszufinden, dass ComboBox.Items eine ObjectCollection zurückgibt und mit einem Editor-Attribut dekoriert ist.

    Hier ist z.B. die Deklaration der Property ComboBox.Items aus dem .NET Sourcecode (man kann statt F11 aber auch Reflector nehmen):

    [Editor("System.Windows.Forms.Design.ListControlStringCollectionEditor, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", typeof(UITypeEditor)), 
    SRDescription("ComboBoxItemsDescr"), 
    MergableProperty(false), 
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content), 
    Localizable(true), SRCategory("CatData")]
      public ObjectCollection Items { get; }
    

     

    Gruß
    Marcel

    Freitag, 3. September 2010 18:48
    Moderator
  • Hallo Marcel,

    genau so hatte ich das auch gemacht.
    Einfach F12 auf Items und die im darüberstehenden Text die Attribute etwas formatiert hier gepostet.
    Ist eigentlich eine Standard-Technik, die irgendwie viele nicht kennen.

    Beachte bitte, dass in dem englischen Link eine Version !2.0.0.0! steht. Mein Vorschlag war bereits auf das .NET 4.0 bezogen, wo !4.0.0.0! benutzt wird!
    Diese Nummer sollte mit der des supporteten .NET Frameworks übereinstimmen.
    Das hatte Manuel sicher schon entdeckt. Zudem sollte auch die Einbindung und deklarative C# Zusammenstellung nicht fehlen, wie etwa in dem englischen Link.

    BTW, der gepostete StringCollectionEditor (s.Thomas) ist nicht ganz das, was die Items Eigenschaft der ComboBox benutzt, es wird intern noch EditValue überschrieben, aber das ist natürlich trotzdem eine gute Möglichkeit, das zu machen, weil fast keine wichtige Funktionalität zusätzlich erstellt wird.
    BTW: die [SRDescription("ComboBoxItemsDescr")] Attribute natürlich ersetzen, oder weglassen, wie in meinem Posting.
      


    ciao Frank
    Freitag, 3. September 2010 20:10
  • Thomas,
       
           > ... die üblichen 'Kopien' nachgereicht wurden.

    so geht das nicht. Bitte vermeide solche privaten Beleidigungen.

    Ich habe hier nur überflogen, dass Du den für die Lösung des Problems nicht exakten StringCollectionEditor gepostet hattest. 
    Ausserdem habe ich eben nicht Deine veraltete Version 2.0, sondern die 4.0 benutzt und weiterhin die viel wichtigere Einbindung und Anwendung des Attributes beschrieben - weit weg von "Kopien".
    Eben genau das, was Manuel (seiner Aussage nach) auch gebraucht hat.

    Es kann trotzdem in diesen Foren vorkommen, das Leute das gleiche oder ähnliches aussagen. Das hilft ggf. auch dem Fragenden, da hier eine Meinung verstärkt wird, wenn zwei sie haben.
    Es geht in diesem Forum nicht um Schnelligkeit, sondern um Hilfe für den Fragenden und Leute, die dort hinschauen auch später. Manchmal kommen auch Kommentare Monate später.


    ciao Frank
    Freitag, 3. September 2010 20:29