Forum: PC-Programmierung Visual C++ .Net ComboBox Elemente frei indizieren


von Markus W. (kornbanane)


Lesenswert?

Hallo Leute,

ich stehe gerade voll auf dem Schlauch. Leider fange ich gerade erst mit 
der Programmierung unter C++ in Visual Studio an.

Ich habe vor eine Anwendung in Visual Studio 2008 unter der Verwendung 
C++ mit .NET und Windows Forms zu erstellen.

Jetzt habe ich eine ComboBox in der der Benutzer z.B. folgende Werte 
auswählen können soll, dabei soll jeder Wert eine ID besitzen. Für die 
ID will ich den Index der Einträger der Combobox verwenden.

ID / Wert

1  / Haus
3  / Auto
5  / Boot

Im späteren Programmablauf soll also z.B. anhand der ausgelesenen ID der 
Auswahl der Combobox mit "comboBox1->SelectedIndex" überprüft werden, 
welche Auswahl der Nutzer getroffen hat.

Ich füge die neuen Elemente wie folgt zu:
1
cbArea->Items->Insert(0,"Haus");
2
cbArea->Items->Insert(1,"Auto");
3
cbArea->Items->Insert(2,"Boot");

Dies funktioniert soweit, allerdings stimmt so die ID nicht mit meiner 
Vorgabe überein. Die Elemente müssten also wie folgt hinzugefügt werden:
1
cbArea->Items->Insert(1,"Haus");
2
cbArea->Items->Insert(3,"Auto");
3
cbArea->Items->Insert(5,"Boot");

Jetzt enthält die Combobox aber garkeine Elemente, da es keine Elemente 
mit dem Index 0 oder 2 gibt.... Und scheinbar kann man nur Elemente mit 
aufsteigendem Index in der Combobox hinzufügen bzw. kann keine Lücken im 
Index hinterlassen.

Wie kann ich dies nun umgehen? Dummy Elemente in die Combobox einfügen 
und diese dann ausblenden?
Dies wäre aber sicher keine gute Lösung.

Oder vielleicht die Verwendung eines 2-Dimensionalen Arrays? Leider 
fehlt mir hierzu die Erfahrung. Über ein kleines Beispiel währe ich sehr 
dankbar ;)

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Markus W. schrieb:
> Wie kann ich dies nun umgehen

man legt eine Strukt an, wo der String und die interne ID gespeichert 
ist. Diese strukt fügt man dann in die Comobox ein.

Ich kann nur C# (warum hast du C++/CLI gewählt)
1
struct  MyItems
2
{
3
   String Text;
4
   int Id;
5
   MyItems( String Text, int Id ) {
6
      this.Text = Text;
7
      this.Id = ID;
8
   }
9
}
10
11
cbArea->Items->Insert( new MyItems("Haus", 42) );

von Flitzomat (Gast)


Lesenswert?

Peter II schrieb:
> (warum hast du C++/CLI gewählt)

Falls dich das irritiert ...

Markus W. schrieb:
> ich stehe gerade voll auf dem Schlauch. Leider fange ich gerade erst mit
> der Programmierung unter C++ in Visual Studio an.
> Ich habe vor eine Anwendung in Visual Studio 2008 unter der Verwendung
> C++ mit .NET und Windows Forms zu erstellen.

Keine gute Idee. Erstens ist das kein "reines" C++, sondern C++/CLI, 
zweitens existiert dieses Template (C++/CLI + Forms) in VS schon lange 
nicht mehr; es wird empfohlen, diese Kombination nicht zu verwenden (*). 
Wenn Windows Forms oder WPF, dann C#. Bei C++ eben C++ - und nicht 
C++/CLI - und eine GUI-Bibliothek (Win32++, Qt, wxWidgets, MFC, WTL, 
...) deiner Wahl. Falls das Betriebssystem es zulässt und sonst nichts 
dagagen spricht, solltest du eine aktuellere Version von VS installieren 
- ab Windows 7 mit SP1 Visual Studio 2015 Community mit Update 3 -, 
alleine schon wegen des inzwischen viel besseren C++-Compilers.

(*)
Beitrag "Re: .dll einbinden C++"

von Markus W. (kornbanane)


Lesenswert?

Danke für die Hilfe,

ich habe mich dazu entschieden auf Visual C# mit Windows Forms 
umzusteigen und habe den Code von Peter II ausprobiert.

Zuerst habe ich den Fehler bekommen
"MyItems" enthält keinen Konstruktor, der 2-Argumente akzeptiert"

Daraufhin habe ich den Konstruktor mit dem Schlüsselwort public 
versehen.

Nun habe ich einen weiteren Fehler:
"Fehler CS1501: Keine Überladung für die Insert-Methode nimmt 1 
Argumente an"

Durch den Aufruf
1
 cbArea.Items.Insert(new MyItems("Haus", 42));

Laut Microsoft MSDN ist der Fehler recht klar
"Eine Klassenmethode wurde aufgerufen, aber keine Definition der Methode 
nimmt die angegebene Anzahl von Argumenten."
Siehe: https://msdn.microsoft.com/de-de/library/d9s6x486.aspx

Ich verstehe dies nicht, schließlich übergebe ich doch nur ein Argument?

von Peter II (Gast)


Lesenswert?

Markus W. schrieb:
> ich habe mich dazu entschieden auf Visual C# mit Windows Forms
> umzusteigen und habe den Code von Peter II ausprobiert.
gute Entscheidung


> Zuerst habe ich den Fehler bekommen
> "MyItems" enthält keinen Konstruktor, der 2-Argumente akzeptiert"

zeige mal bitte den aktuellen code, dann ist es einfacher zu helfen.

von Markus W. (kornbanane)


Lesenswert?

Hallo Peter, hier der Code:
1
struct MyItems
2
{
3
    String Text;
4
    int Id;
5
6
    public MyItems(String Text, int Id)
7
    {
8
        this.Text = Text;
9
        this.Id = Id;
10
    }
11
}

und dann im Event Form1.load
1
    public partial class Form1 : Form
2
    {
3
        public Form1()
4
        {
5
            InitializeComponent();
6
        }
7
8
        private void Form1_Load(object sender, EventArgs e)
9
        {
10
   
11
            cbArea.Items.Insert(new MyItems("Haus", 42));
12
13
            cbArea.SelectedIndex = 0;
14
15
        }
16
    }

von Peter II (Gast)


Lesenswert?

Markus W. schrieb:
> .Items.Insert(new MyItems("Haus", 42));

insert ist jetzt falsch.

verwende mal
1
 cbArea.Items.Add(new MyItems("Haus", 42));

dann braucht man noch ein ToString Methode:

1
struct MyItems
2
{
3
    String Text;
4
    int Id;
5
6
    public MyItems(String Text, int Id)
7
    {
8
        this.Text = Text;
9
        this.Id = Id;
10
    }
11
12
    public String ToString() 
13
    {
14
       return Text;
15
    }
16
}

von Markus W. (kornbanane)


Lesenswert?

Hallo Peter,

jetzt scheint es zu funktionieren. Es gibt nur noch ein Problem:

Wenn ich die drei Elemente in meine Combobox einfüge:
1
cbArea.Items.Add(new MyItems("Auto", 40));
2
cbArea.Items.Add(new MyItems("Haus", 42));
3
cbArea.Items.Add(new MyItems("Garten", 43));

Und das programm ausführe, erhälte ich 3 mal die Auswahl "MyItems" :D

von Peter II (Gast)


Lesenswert?

Markus W. schrieb:
> Und das programm ausführe, erhälte ich 3 mal die Auswahl "MyItems" :D

naja, Kleinigkeiten

neuer versuch:

[c]
struct MyItems
{
    String Text;
    int Id;

    public MyItems(String Text, int Id)
    {
        this.Text = Text;
        this.Id = Id;
    }

    public virtual string ToString()
    {
       return Text;
    }
}
[c]

von Markus W. (kornbanane)


Lesenswert?

Hmm, folgender Fehler kommt bei raus:

"Fehler CS0106: Der virtual-Modifizierer ist für dieses Element nicht 
gültig."

von Kollege von oben (Gast)


Lesenswert?

Es ist ganz einfach mach aus der Struct eine Classe,
lasse diese von "Objekt" erben.

Und die ToString Methode muss als override deklariert werden

von Peter II (Gast)


Lesenswert?

Markus W. schrieb:
> Hmm, folgender Fehler kommt bei raus:

ja sorry, kann es hier nicht testen.

neuer versuch
1
struct MyItems
2
{
3
    String Text;
4
    int Id;
5
6
    public MyItems(String Text, int Id)
7
    {
8
        this.Text = Text;
9
        this.Id = Id;
10
    }
11
12
    public override string ToString()
13
    {
14
       return Text;
15
    }
16
}

von Markus W. (kornbanane)


Lesenswert?

Super, vielen Dank es funktioniert.

Nun ist nur noch die Frage wie ich die einzelnen Daten des über die 
Combobox ausgewählten Elementes abfragen kann.

Ich habe es folgendermaßen versucht, leider ohne Erfolg...
1
// Für die Ausgabe des Textes
2
label1.Text = cbArea.SelectedItem.Text.ToString();
3
4
// Für die Ausgabe der ID
5
label2.Text = cbArea.SelectedItem.Text.ToString();


Mit "SelectedItem.ToString();" kann ich zwar den Text schon abfragen, 
aber wie komme ich an die ID bzw. wenn meine Structur noch mehr Daten 
enthält an diese?

von Peter II (Gast)


Lesenswert?

Markus W. schrieb:
> label1.Text = cbArea.SelectedItem.Text.ToString();

du musst das orginal Objekt raushohlen.
1
MyItem tmp = (MyItem)cbArea.SelectedItem();
2
int id = tmp.GetId();

die Methode GetId musst du noch in die Strukt einbauen.

von Markus W. (kornbanane)


Lesenswert?

Hallo Peter,

leider erhalte ich folgende Fehlermeldung:

Fehler CS1955: Der nicht aufrufbare Member 
"System.Windows.Forms.ComboBox.SelectedItem" kann nicht wie eine Methode 
verwendet werden.

von Kollege von oben (Gast)


Lesenswert?

Das liegt daran das SelectedItem keine Methode ist.

von Kollege von oben (Gast)


Lesenswert?

Also lass die klammern weg und es geht

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.