7.6k Aufrufe
Gefragt in Anwendungen(Java,C++...) von
Hallo zusammen! Ich habe ein kleines Problem und dazu eine Frage. Ich arbeite mit C# (bin noch Anfänger) und möchte folgendes tun:
In einer Form1 befindet sich eine Listbox1 und darin befinden sich 5 Einträge (X1, X2...,X5).
In einer Form2 befindet sich ein Label1.
Ich möchte nun erreichen, wenn ich z.B. auf den Eintrag X3 klicke, dass sich Form2 öffnet und im Label1 der Text X3 steht.
Ich habe das schon mit der Erstellung von neuen Instanzen versucht - klappt nicht. Auch der Versuch mit der Übergabe eines Parameters klappte nicht.
Kann mit bitte jemand behilflich sein und mir ein wenig auf die Sprünge helfen? Ich bin sicher das ist ganz einfach - nur ich komm nicht drauf. Danke schon mal im Voraus, Claudia.

26 Antworten

0 Punkte
Beantwortet von computerschrat Profi (33.3k Punkte)
Hallo Claudia,

ich hgabe das nochmal getestet und verstehe den von Dir beschriebenen Absturz nicht.
Wenn nach dem Start der erste Klick zwar in die Listbox, aber auf einen freien Platz ohne Eintrag geht, dann wird Index auf 99 und curItem auf den Text "Fehler" gesetzt. Wenn der Klick auf einem bestehenden Eintrag der Listbox landet, dann wird der Index auf die Nummer des Eintrages gesetzt (beginnend mit 0 für den ersten Eintrag) und zusätzlich wird curItem mit dem gewählten Eintrag belegt. An der Stelle, an der ich den Kommentar // Hier die Auswertung stehen habe, musst Du nun index auswerten und entsprechend reagieren. Entweder gibst Du den Text curItem in form2.Label aus oder Du sendest eine Meldung wegen des falschen Klick.

Gruß
computerschrat
0 Punkte
Beantwortet von
Hallo computerschrat,
erst einmal danke für den Tip. Ich habe das genauso eingegeben, wie Du es mir geschrieben hast. Da wo dann steht //Hier die Auswertung habe ich folgendes eingefügt:

if(index==99)
MessageBox.Show(curItem);

Ich dachte eigentlich es würde so ausreichen, aber es kommt leider die Fehlermeldung:

"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

Dabei habe ich dann die Möglichkeit auf Weiter oder Beenden zu klicken oder auf Details. Bei Beenden wird die Anwendung geschlossen, bei Weiter verschwindet die Fehlermeldung, erscheint aber beim nächsten Klick wieder und bei Detail steht jede Menge drin.

Wo liegt der Fehler? Besten Dank, C.
0 Punkte
Beantwortet von computerschrat Profi (33.3k Punkte)
Hallo Claudia,

prüfe doch nochmal genau, ob im Fehlerfall (Klick ins Leere) die Deklaration von curItem und index auch wirklich durchlaufen werden und ob eine Zuweisung an beide gemacht wird. Ich habe das gerade eben versucht und habe in meine oben gezeigte Quelle genau Deine Anweisung
if (index==99)
MessageBox.Show(curItem);
bei der Auswertung eingebaut und das funktioniert. Wenn ich in einen leeren Teil der Listbox klicke, kommt diese MessageBox hoch und sagt "Fehler".

Gruß
computerschrat
0 Punkte
Beantwortet von
Hallo computerschrat,
danke für die Info, aber ich habe keine Ahnung wie das bei Dir funktioniert. Deshalb nochmal folgendes - probier das bitte einfach mal aus:
################# Code in Form 1 ############################
public partial class Form1 : Form
{
private Form2 _form2;

public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
listBox1.Items.Clear();
listBox1.Items.Add("Eintrag 1");
listBox1.Items.Add("Eintrag 10");
listBox1.Items.Add("Eintrag 100");
listBox1.Items.Add("Eintrag 1000");
listBox1.Items.Add("Eintrag 10000");
}

private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
this._form2 = new Form2();

string curItem = listBox1.SelectedItem.ToString();
int index = listBox1.FindString(curItem);

this._form2.label1.Text = curItem;
this._form2.Show();
}

private void listBox1_Click(object sender, EventArgs e)
{
int index;
string curItem = "";
try
{
curItem = listBox1.SelectedItem.ToString();
index = listBox1.FindString(curItem);
}
catch
{
index = 99; // Hier gehts hin, wenn ein Fehler auftritt
curItem = "Fehler";
}

// Hier die Auswertung
if (index == 99)
MessageBox.Show(curItem);

}

private void button1_Click(object sender, EventArgs e)
{
//listBox1.Items.Clear();
//listBox1.Items.Add("Eintrag 1");
//listBox1.Items.Add("Eintrag 10");
//listBox1.Items.Add("Eintrag 100");
//listBox1.Items.Add("Eintrag 1000");
//listBox1.Items.Add("Eintrag 10000");
listBox1.SelectedIndex = -1; // Soll die Markierung eines Eintrages in der Listbox aufheben.
}


}

In Form 2 steht nichts drin, sieht also so aus:

############## Code in Form 2 #############################
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
}

Jetzt mal einfach das Programm starten und auf einen gültigen Eintrag in der Listbox klicken. Es sollte sich die neue Form2 öffnen und im Label dieser Form sollte das stehen, worauf die in der Listbox geklickt hast. Wenn das so ist dann ist alles prima.
Jetzt mal auf den Button klicken und damit die Auswahl in der Listbox quasi aufheben - ist eigentlich dasselbe, als wenn Du in einen ungenutzten Bereich der Listbox klicken würdest.. Und da müßtest Du auch eine Fehlermeldung erhalten die dann so aussieht:

"Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt."

Aber eine MessageBox mit "Fehler" erscheint bei mir nicht. Ach so ich weiß nicht welche Version von C# Du nutzt - ich "probiere" mit der Express Version von Visual Studio 2010.

Gruß, Claudia.
0 Punkte
Beantwortet von computerschrat Profi (33.3k Punkte)
Hallo Claudia,

bei mir kommt die MessageBox so wie sie soll und es gelingt mir nicht, die Fehlermeldung zu generieren.
Ich dachte schon einen Unterschied gesehen zu haben, da Du das Click-Ereignis, benutzt und ich das SelectedIndexChanged-Ereignis. Das ändert aber nichts.

Ich benutze die Version 2012 von Visual Studio express. Ich kann mir aber nicht vorstellen, dass darin das Problem liegt.
Ich biete nochmal an mein Projekt auf einen FTP Server zu laden und Dir einen Account dafür zu geben. Dann kannst Du mein Projekt mal laden und bei Dir testen. Den Account möchte ich aber nicht öffentlich hier verteilen und für private Nachrichten über das Supportnet brauchts die Anmeldung bei SN. Du könntest mir im Gegenzug bei Interesse auch Dein Projekt hochladen und ich schaue da mal drüber.

Gruß
computerschrat
0 Punkte
Beantwortet von computerschrat Profi (33.3k Punkte)
Hallo Claudia,

Ich glaube, jetzt habe ich das Problem gefunden.
Im Ereignis listBox1_selectedItemChanged ist keine Fehlerbehandlung. Hier wird
unbedingt der index genommen und das dazugehörige Item aus der Listbox gelesen.
Im Falle des falschen Clicks zeigt der Index aber ins Leere. Diesen Teil hatte ich bei
meinem Test Nicht wieder aus dem Thread übernommen und bei mir war die try-
catch Fehlerbehandlung noch drin.
Schau da nochmal genau hin. Du kannst den gesamten Inhalt des
selectedIndexChanged Ereignisses auskommentiern. Die Auswertung hast Du ja im
Click-Ereignis drin.

Gruß
computerschrat
0 Punkte
Beantwortet von
Hallo computerschrat,
danke erst einmal für die Tips. Ich habe es inzwischen etwas anders gemacht, es gibt also keinen freien Platz in der Listbox mehr, egal wohin der Klick geht, es wird immer ein gültiger Eintrag getroffen (trotzdem bleibe ich aber an der Fehlermeldung dran - will unbedingt was damit ist).
Dir das ganze Projekt zu schicken, wäre echt bisschen aufwendig, deswegen beschränke ich mich mal auf die wichtigsten Dinge:
Form1 enthält eine Listbox1, in dieser stehen 24 Einträge wie z.B. dieser hier:
"1. Mexico City" oder "2. Madrid" (allerding ohne diese "")
Wenn ich jetzt auf einen Eintrag in dieser Listbox1 klicke soll sich eine Form2 öffnen in der sich ein Label1 und ein Label2 befinden.
Im Label1 soll die aktuelle Uhrzeit der ausgewählten Stadt stehen und im Label2 soll der Name der Stadt selbst stehen. In der Titelleiste der Form2 steht dann z.B. "1. Zeitzone" wobei ich "1." aus dem Listboxeintrag herausfiltern möchte. Und eine Form2 für den jeweiligen Eintrag soll auch nur geöffnet werden, wenn nicht bereits schon eine geöffnet wurde. Die aktuelle Uhrzeit der Zeitzone im Label1 soll dabei auch noch im Sekundentakt aktualisiert werden, eben aktuell sein. Eigentlich so was wie eine Weltzeituhr.
Ich will Dir wirklich nicht auf die Nerven gehen, aber für Tips bin ich immer dankbar - letztendlich will das ja auch richtig lernen.
Danke für Geduld und Hilfe, Claudia.
0 Punkte
Beantwortet von computerschrat Profi (33.3k Punkte)
Hallo Claudia,

Die Geschichte mit den Zeitzonen würde ich folgendermaßen angehen:
Die Zeitzonen nummerieren mit 1..24 (wobei es ja auch ein paar Zeitzonen mit 0,5 Stunden Verschiebung zum Nachbarn gibt)
Jetzt erzeugst Du ein Array mit 24 Strings, das die Namen der Zeitzonen 1..24 enthält, sowie ein Array mit 24 Integers, das die Verschiebung der Zeitzone zu GMT beinhaltet.
Im Form1 erstellst Du wie gehabt die Listbox mit den 24 Namen der Zeitzonen. Am geschicktesten baust Du eine for each Schleife über alle Elemente des Arrays mit den Namen und addest damit jede Zeitzone zur ListBox. Dann kannst Du später noch die halbstunden Zeitzonen dazunehmen, ohne am Programm etwas ändern zu müssen.

Wenn Du dann auf einen Listeneintrag klickst, wird, wenn erforderlich, eine neue Instanz von Form2 erzeugt und sichtbar geschaltet. Den Kopftitel kannst Du frei wählen und den Eintrag im Label2 aus dem Listeneintrag übernehmen. Zum Herausfiltern der 1. vor dem Namen kannst Du die Split Funktion verwenden, die nach einem definierten Trennzeichen sucht und den String in den Teil vor und nach diesem Zeichen zerlegt.
Für die Uhrzeitanzeige nimmst Du die aktuelle Zeit und addierst die zur Zeitzone gehörende Zeitdifferenz dazu. Am einfachsten nimmst Du eine Variable vom Typ DateTime und weist ihr den Wert now zu. Mit AddMinutes() addierst Du die Zeitverschiebung dazu und hast die aktuelle Zeit der gjeweiligen Zeitzone.. Die Zeitdifferenz findet sich über den selectedIndex der Listbox in dem Array mit den Zeitdifferenzen.
Jetzt brauchst Du auf dem Form2 noch einen Timer mit 1000mS Intervall. In dessen Ereignisroutine berechnest Du die Zeit für diese Instanz von Form2 neu und legst sie in das Label1.

Achte bei dem Timer darauf, dass er beim Schließen eines forms abgeschaltet wird (timerx.enabled=false) Andernfalls stürzt das System irgendwann ab, weil der Timer läuft, aber keine Behandlungsroutine für ihn mehr da ist.
Klingt kompliziert, braucht aber vermutlich nicht mehr als zwei bis drei Bildschirmseiten Code.

Viel Erfolg!

Gruß
computerschrat
0 Punkte
Beantwortet von
Hallo computerschrat,
danke für die Tipps, aber ich hab da noch ein Problem. Das mit der Ortangabe habe ich gepackt, aber ich habe keine Peilung wie ich das mit der Zeit machen soll - es steht in dem neuen Formular welches sich öffnet immer dieselbe Zeit die auch hier aktuell ist, weil ich nicht weiß, wie ich auf die Differenz zugreifen kann. Mein Quellcode sieht zur Zeit so aus:
################### Form1 #######################
public partial class Form1 : Form
{
string[] ort;
int[] diff;

public Form1()
{
InitializeComponent();
ort = new string[] { "Midway Island", "London", "Wellington" };
diff = new int[] { -11, +0, +12 };
}

private void Form1_Load(object sender, EventArgs e)
{
foreach (string str in ort)
listBox1.Items.Add(str);
}

private void listBox1_SelectedValueChanged(object sender, EventArgs e)
{
Form2 _frm2 = new Form2();
_frm2.label1.Text = listBox1.SelectedItem.ToString();
_frm2.Show();
}
}

##################### Form2 ############################
public partial class Form2 : Form
{

public Form2()
{
InitializeComponent();
}

private void timer1_Tick(object sender, EventArgs e)
{
DateTime zeit = DateTime.Now;
string f = "HH:mm.ss";
label2.Text = zeit.ToString(f);

}

private void Form2_Load(object sender, EventArgs e)
{
timer1.Enabled = true;
DateTime zeit = DateTime.Now;
string f = "HH:mm.ss";
label2.Text = zeit.ToString(f);
}
}

Ich hab das Ganze auch mal auf nur 3 Einträge in der Listbox reduziert. Hast Du eine Idee was da falsch sein könnte - mir fällt dazu echt nichts mehr ein und meine Literatur hilft mir auch nicht weiter. Danke und Gruß + schönen Sonntag, Claudia.
0 Punkte
Beantwortet von computerschrat Profi (33.3k Punkte)
Hallo Claudia,

über
listBox1.SelectedIndex;
kannst Du direkt auf den angewählten Index aus der Listbox zugreifen.
Mit diesem Index kannst Du ais dem Array mit den Zeitverschiebungen den aktuellen Wert lesen:

Zeitdifferenz = diff[listBox1.SelectedIndex];

Die Lokale Zeit kannst Du dann in form2 jeweils berechnen über

LokaleZeit = zeit.AddMinutes(Zeitdifferenz);

LokaleZeit musst Du natürlich in form2 als Zeit deklarieren und die Zeitdifferenz musst Du in jeder Instanz von form2 speichern, da dort über den TImer jede Sekunde wieder drauf zugegriffen werden soll.

Gruß
computerschrat
...