Ausgabe Combobox formatieren



  • Hier mal was ich gemacht habe ... würde es ja gerne selber schaffen 🙂

    {
    	    ...
                IEnumerable<Kunde> kundenEintraege = AlleKunden();
                DropDownWidth();
    
                cbKunde.Items.AddRange(KundenListeFormatiert(max1).ToArray());
                int iLaenge = max1;
                cbKunde.DropDownWidth = iLaenge;
                cbKunde.DisplayMember = "anzeigenKundeOrt";
            }
    
            void DropDownWidth()
            {
                int temp = 0;
                int maxWidth = 0;
    
                foreach (Kunde k in kundenEintraege)
                {
                    temp = TextRenderer.MeasureText(k.Name.ToString(), cbKunde.Font).Width;
                    if (temp > maxWidth)
                    {
                        maxWidth = temp;
                    }
                }
                max1 = maxWidth;
            }
    
            List<Kunde> KundenListeFormatiert(int iMax)
            {
                List<Kunde> kundenFormatiert = new List<Kunde>();
    
                foreach (Kunde neu in kundenEintraege)
                {
                    string s = neu.Name.PadRight(iMax);
    
                    kundenFormatiert.Add(new Kunde() { Name = s });
                }
    
                return kundenFormatiert;
            }
    


  • Bin ich damit grob auf dem richtigen Weg?? 😕



  • Nein Du musst nicht mit TextRenderer.MeasureText hantieren. Für beliebige Schriftarten ist es sowieso nicht möglich. Also nochmal: Monospace-Font wie Courier-New einstellen und mit dem Length-Property der string-Klasse die Länge ermitteln. Ausgehend vom längsten die restlichen mit Leerzeichen füllen.

    Oder auf eine fertige Lösung zurückgreifen...



  • Insgesamt geht es nun schon in die richtige Richtung.

    kundenEintragslaenge = AlleKunden();
    List<string> kundenListe = DropDownWidth();
    cbTest.DataSource = kundenListe;
    
            List<string> DropDownWidth()
            {
                int iLength = 0;
                int iMaxLength = 0;
    
                foreach (Kunde k in kundenEintragslaenge)
                {
                    iLength = k.Name.Length;
                    if (iLength > iMaxLength)
                    {
                        iMaxLength = iLength;
                    }
                }
    
                return KundenListeFormatiert(kundenEintragslaenge, iMaxLength);
            }
    
            List<string> KundenListeFormatiert(IEnumerable<Kunde> lstKunden, int iLength)
            {
                List<string> kundenFormatiert = new List<string>();
    
                foreach (Kunde k in lstKunden)
                {
                    string s = k.Name.PadRight(iLength, ' ');
                    s = s + "| Testort";
                    kundenFormatiert.Add(s);
                }
    
                return kundenFormatiert;
            }
    

    Allerdings wird der angehängte Testort teilweise noch um ein oder zwei Zeichen versetzt dargestellt!?



  • Du fügst ja auch überall die gleiche Anzahl Leerzeichen an, was garkeinen Sinn macht.
    Eher sowas:

    k.Name.PadRight(iLength - k.Name.Length + 1, ' ');
    


  • So, ich bin nun doch auf eine fertige Lösung umgestiegen ...

    Folgendes Beispiel verwende ich: http://www.c-sharpcorner.com/uploadfile/a644fc/multicolumn-combobox-with-configurable-display-and-value-members-and-fast-search-functionality/

    // Einbinden in die Form.
    private void Form1_Load(object sender, System.EventArgs e)
    {
                this.Controls.Add(multiColumComboBox1);
                var point = new Point(550, 15);
                this.multiColumComboBox1.Location = point;
    
                InitializeComboBox();
    }
    
    // Aufruf wie im Beispiel.
    
            private void InitializeComboBox()
            {
                multiColumComboBox1.Clear();
                multiColumComboBox1.SourceDataString = new string[3] { "ID", "Name", "Code" };
                multiColumComboBox1.ColumnWidth = new string[3] { "150", "200", "50" };
                multiColumComboBox1.DataSource = GetDataSource();
            }
    
            private DataTable GetDataSource()
            {
                //DataTable dtSource = D_Verkauf.GetAlleKundenTableTest();
                DataTable dtSource = new DataTable();
                DataColumn dtColID = new DataColumn("ID");
                dtColID.DataType = System.Type.GetType("System.String");
                dtSource.Columns.Add(dtColID);
    
                DataColumn dtColName = new DataColumn("Name");
                dtColName.DataType = System.Type.GetType("System.String");
                dtSource.Columns.Add(dtColName);
    
                DataColumn dtColCode = new DataColumn("Code");
                dtColCode.DataType = System.Type.GetType("System.String");
                dtSource.Columns.Add(dtColCode);
    
                //Add rows
                DataRow row = dtSource.NewRow();
                row[dtColID] = "1";
                row[dtColName] = "Vijay";
                row[dtColCode] = "1001";
                dtSource.Rows.Add(row);
    
                //Add rows
                row = dtSource.NewRow();
                row[dtColID] = "2";
                row[dtColName] = "Ajay";
                row[dtColCode] = "1002";
                dtSource.Rows.Add(row);
    
                //. . . . .
                //. . . . .
    
                return dtSource;
            }
    

    Die MultiColumnBox wird auch angezeigt, jedoch 'passiert' nichts ... es wird nichts angezeigt.
    Hab ich dabei etwas vergessen? 😕



  • Wenn der Code wie gezeigt ausgeführt wird, wundert mich, dass dir beim Compilieren nicht schon ein Fehler vor die Füß geworfen wird. Erste Zeile ind er Methode GetDataSource ist auskommentiert. Anschließend setzt du eine leere Datenquelle.



  • Die Datenquelle wird doch anschließend von Hand gefüllt. Ist im Beispiel ebenso (bis auf die auskommentierte Zeile).
    Die auskommentierte Zeile ist wäre der Weg über die Datenbank.

    Die Datasource enthält auch Zeilen, gebunden an eine ComboBox erhalte ich auch Daten.



  • War doch alles durchgestrichen?



  • Hatte den EventHandler vergessen 🙄
    Jetzt klappt es! Danke Euch!



  • Kann mir vielleicht noch jemand damit helfen, wie ich ein TextChanged Event für die Textbox innerhalb der MultiColumnComboBox erstellen kann?

    Ziel wäre (wie bei einer normalen Combobox), dass wenn der User einen Buchstaben/Text eingibt direkt zu den Einträgen mit diesem Anfangsbuchstaben gesprungen wird (im Idealfall sogar gefiltert).



  • Hier mal der Anfang:

    public event EventHandler TextBoxTextChanged;
    
            private void HandleTextboxTextChanged(object sender, EventArgs e)
            {
                this.OnTextboxTextChanged(EventArgs.Empty);
            }     
            protected virtual void OnTextboxTextChanged(EventArgs e)
            {
                EventHandler handler = this.TextBoxTextChanged;
                if (handler != null)
                {
                    handler(this, e);
                }
            }  
    
     private void txtbox_TextChanged(object sender, EventArgs e)
            {
                if (TextBoxTextChanged != null)
                {
                    TextBoxTextChanged(this, e);
                }
            }
    

    Leider erhalte ich, sobald ich einen Buchstaben eintippe eine StackOverflowException?!



  • Willst du nicht eher

    private void txtbox_TextChanged(object sender, EventArgs e)
    {
        OnTextboxTextChanged(EventArgs.Empty);
    }
    

    ?!!

    P.S. Deine HandleTextboxTextChanged-Methode ist nur dann sinnvoll, wenn du die Parameter wegläßt:

    private void HandleTextboxTextChanged()
    {
        OnTextboxTextChanged(EventArgs.Empty);
    }
    

    So kannst du dann in der oberen Methode dann auch einfach diese aufrufen!

    PPS: Wenn du noch mehr Details dazu wissen willst, dann kannst du dir mal meinen Artikel Kommunikation von 2 Forms anschauen, der u.a. auch Ereignisse behandelt.


Anmelden zum Antworten