Ausgabe Combobox formatieren
-
berniebutt schrieb:
Du solltest für die ComboBox unter der Eigenschaft ´Font´ die Schriftart ´Courier New´ einstellen.
Doppelt hält besser oder wieso spielst du den Papagei?
-
Im Prinzip hab ich es verstanden.
Leider weiß ich nicht, wie ich die Länge der ersten "Spalte" ermitteln kann bzw. auch zu welchem Zeitpunkt ich das machen muss.Ich kann zwar die Länge einer Spalte ermitteln, aber erst dann, wenn die Daten bereits gebunden sind.
-
Gernot_HH schrieb:
Im Prinzip hab ich es verstanden.
Leider weiß ich nicht, wie ich die Länge der ersten "Spalte" ermitteln kann bzw. auch zu welchem Zeitpunkt ich das machen muss.Ich kann zwar die Länge einer Spalte ermitteln, aber erst dann, wenn die Daten bereits gebunden sind.
Du bindest entweder per Winforms-Databinding Deine Items an die Combobox, oder fügst sie per Schleife hinzu. Auf jedenfall hast Du vorher eine vollständige Liste aller Einträge für die Box.
Zu dem Zeitpunkt ermittelst Du den längsten Namen. Damit hast Du schonmal die Anzahl der Leerzeichen die Du in die anderen Einträge nach dem Namen einfügen musst. Für die anderen Spalten ergeben sich ähnliche Probleme die aber nach diesem Schema erschlagen werden können.Zeige mal ein bisschen Code. Zeige mal was Du bisher so gemacht hast. Wenn Du ein vollständiges Minimalbeispiel(*) lieferst, programmiere ich Dir den Rest morgen.
Grüße.
* Code der per Copy&Paste ein funktionierendes Projekt ergibt (inkl. *.Designer.cs Datei) und nichts außer der Problemstellung enthält
-
Das gibt es schon alles fertig, z.B.
http://www.codeproject.com/Articles/10030/Multi-column-Combo
http://www.codeproject.com/Articles/19781/A-data-bound-multi-column-combobox
http://www.codeproject.com/Articles/11899/Auto-Complete-Multi-Column-ComboBox
-
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.