| 

.NET C# Java Javascript Exception

3
Hallo,
ich möchte in einer Funktion ein Popup anzeigen lassen (show()) während der Code weiterläuft bis ich die Form wieder schliesse (Close()).
Das Problem ist, dass die Form zwar hochpoppt aber der Inhalt nicht da ist. Dh wird nicht neu gezeichnet trotz Invalidate(). Ich hab auch schon versicht den Aufruf der Form in einen extra Thread zu verlegen klappt aber auch nicht.
Hat mir jemand ein Beispiel/Link wie ich das am besten lösen kann?
Also einfach nur eine Form anzeigen mit einem Text drauf.

Danke und Gruß
23.02.2012
T.Mann11 43 1 5
Poste mal den Code, der nicht funktioniert, dann findet sich sicher schnell jemand, der Dir weiterhelfen kann. Ich persönlich versteh nicht so ganz, wie ich Dir konkret helfen kann, sonst hätt ich es statt diesem Kommentar versucht...
ffordermaier 23.02.2012
Freut mich, dass ich helfen konnte.

Es wäre aber nett, wenn Du die Lösung auch als richtig markieren würdest.
Andreas Ganzer 24.02.2012
5 Antworten
3
Ein Invalidate reicht nicht, weil die WM_PAINT-Nachreichten dabei lediglich in einer Warteschlange eingetragen werden. Um die Warteschlange abzuarbeiten, muss Application.DoEvents aufgerufen werden. Fürge das mal hinter einem Invalidate ein, dann sollte sich das Fenster auch zeichnen.

Das obere gilt für Windows.Forms. Als Ergänzung für die, die das gleiche Problem in WPF haben, hier eine Funktion, die für WPF das nicht vorhandene Application.DoEvents simuliert:

/// <summary>
/// Forces the UI to update itself.
/// </summary>
///
/// <remarks>
/// This is an analogy to Application.DoEvents() in Windows.Forms.
/// </remarks>
///
protected static void ForceUIUpdate()
{
DispatcherFrame frame = new DispatcherFrame();

Dispatcher.CurrentDispatcher.BeginInvoke(
DispatcherPriority.Background,
new DispatcherOperationCallback(f =>
{
((DispatcherFrame)f).Continue = false;
return null;
}),
frame);

Dispatcher.PushFrame(frame);
}


Das muss im UI-Thread aufgerufen werden.
24.02.2012
Andreas Ganzer 1,4k 1 8
Wie komme ich den zu der DoEvents-Methode?
Wenn ich die einfügen will, dann gibts die nicht.
Application ist bekannt, aber nach dem "." kommt dann im Auswahlfeld nichts mit DoEvents.
Danke
T.Mann11 24.02.2012
Ok, 10 sek später gemerkt, dass die Methode in der Form aufgerufen werden muss...
Funktioniert einwandfrei.
Thx
T.Mann11 24.02.2012
2
Moin,

fehlt vll InitializeComponent() für dein Popup form?

Edit

Hier mein funktionierender Code. Als erstes das Main Form

public partial class Main : Form
{
public Main()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
// Encapsulate ShowPopup method into thread start delegate
var work = new ThreadStart(ShowPopup);

// define the thread
var myThread = new Thread(work);

// run the thread
myThread.Start();

// Wait one second before showing message box
Thread.Sleep(1000);

MessageBox.Show("End of code in GUI Thread has been reached.");
}

/// <summary>
/// Shows the popup for 5 seconds
/// </summary>
/// <returns></returns>
private void ShowPopup()
{
frmPopup.ShowAutoClose(5000);
}
}


Und hier der Code vom Popup

public partial class frmPopup : Form
{
private Timer closeTimer;

public frmPopup()
{
InitializeComponent();
}

public frmPopup(int closeInterval)
{
// do not forget this line!
InitializeComponent();

// start a internal timer that close your popup on tick
closeTimer = new Timer { Interval = closeInterval };
closeTimer.Tick += closeTimer_Tick;
closeTimer.Start();
}

private void closeTimer_Tick(object sender, EventArgs e)
{
// this gets executed every timer tick, we want to execute this once
// to close the form
closeTimer.Stop();
closeTimer.Dispose();
Close();
}

internal static void ShowAutoClose(int closeInterval)
{
var popupForm = new frmPopup(closeInterval);
popupForm.ShowDialog();
}
}


Beste Grüße und viel Erfolg,

Nicolai
24.02.2012
Nicolai Schönberg 2,4k 2 9
1
Hier der Code:
Aufgerufen wird die Funktion "StarteAlles". Hier wird ein Thread erzeugt der eine Form anzeigen soll.
Die Form wird also angezeigt und der Code läuft weiter. Das wird mit der for-Schleife simuliert.
Danach wird die Form wieder geschlossen.
Die Form selbst wird im Thread mit den Funktionen ShowWindow und CloseWindow auf zu gemacht.
Das Ganze funktioniert theroretisch schon, das Problem ist nur, dass der Inhalt der Form nicht
gezeichnet wird. Dh ich habe zwar das Fenster der Form, aber darin ist nicht mein Text, der in
einer normalen textbox steht

Thx


public class Aufruf
{
public int StarteAlles
{
WindowThread threadObject = new WindowThread();
Thread mythread = new Thread(threadObject.ShowWindow);

mythread.Start();

for (int i = 1; i < 40; i++)
{
Thread.Sleep(50);

}

threadObject.CloseWindow();



return 1;
}




class WindowThread
{

private int StopIt = 0;

public void ShowWindow()
{
WindowTimeout ttt = new WindowTimeout();

ttt.ShowInTaskbar = true;
ttt.TopMost = true;
ttt.Focus();
ttt.BringToFront();
ttt.Activate();

ttt.Show();

while (StopIt == 0)
Thread.Sleep(100);
}


public void CloseWindow()
{
StopIt = 1;
//ttt.Hide();
//ttt.Close();
}

}
23.02.2012
T.Mann11 43 1 5
Eiger 1,9k 2 9
1
OK, jetzt wo das soweit funktioniert wollte ich im Popup einen Zähler hochzählen lasssen.
Ich dachte dazu füge ich einen Timer ein und mache das dann im timer_tick.
Allerdings tut sich da garnichts bzw. der timer scheint nicht loszulaufen.

Der Aufruf-Code sieht so aus (jetzt wieder one Thread):
public int WindowTest(int Timeout_s)
{
WindowTimeout ttt = new WindowTimeout();

ttt.ShowInTaskbar = true;
ttt.TopMost = true;
ttt.Focus();
ttt.BringToFront();
ttt.Activate();

ttt.Show();
ttt.Invalidate();
ttt.UpdateForm();

for (int i = 1; i < 40; i++)
{
Thread.Sleep(50);
}

ttt.Hide();
ttt.Close();

return 1;
}


Der Code der Form ist so:
public void UpdateForm()
{
textBox_header.Text = "Please wait...";
this.Invalidate();
this.BringToFront();
this.Activate();
timer1.Interval = 50;
timer1.Start();
Application.DoEvents(); //Daurch wird die Form aktualisiert
}

private void timer1_Tick(object sender, EventArgs e)
{
textBox_header.Text = "timertick läuft";
MessageBox.Show("test");
Application.DoEvents();
}
24.02.2012
T.Mann11 43 1 5
Es ist wohl so, dass durch ttt.Show() die Eventstrukturen nicht gestartet/erstellt werden. Wenn ich ShowDiaolog verwende und den timer1.Start() in den Konstruktur verschiebe dann läuft der timertick.
Allerdings tut nantürlich der ShowDialog das Code-fortsetzen verhindern...
Ich brauche also einen Befehl um die Eventstrukturen manuell zu starten bei Verwendung des Show().
T.Mann11 24.02.2012
Schau dir mein Beispiel an, es funktioniert ohne Probleme. Ich weiß gar nicht was ihr da für ein Heckmeck mit .DoEvents() veranstaltet ... ;)
Nicolai Schönberg 24.02.2012
Ich nehme an, dass dein Beispiel auch nicht funktionieren wird da du auch "ShowDialog" verwendest. Wenn das aufgerufen wird dann bleibt der Code stehen bis er wieder zu ist. Deshalb wollte ich nur "Show()" verwenden.
T.Mann11 24.02.2012
Deine Annahme ist aber falsch. Der Code läuft weiter
Nicolai Schönberg 24.02.2012
0
Der Unterschied ist, dass dein Beispiel in einer Windows-Form läuft. Ich versuche das ganze als DLL zu machen (hätte ich vielleicht erwähnen sollen :-)).
24.02.2012
T.Mann11 43 1 5

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH