Diskuze: Dialog ve druhém formuláři blokuje první formulář
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.

Člen

Zobrazeno 20 zpráv z 20.
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Form2 otevírám z Form1 tímto kódem
Form2 Dvojka = new Form2();
Dvojka.Start();
Form3 ve Form2 pak
Form3 Trojka = new Form3();
Trojka.ShowDialog();
Potřebuj docílit toho aby Form1 byl stále aktivní, ale Form2 se po otevření Form3 deaktivoval.
Jelikoz Form3 oteviras ve Form2 jako dialog, nemuzes Form2 uzavrit. Takze
doporucuju prehodnotit logiku aplikace/kodu. Ja bych resil otevreni Form2 z
Form1 a pokud dojde k naplneni nejake podminky pak uzavru Form2 a na zaklade
vyvolane udalnosti (Closed, Closing) pri uzavirani Formu2 otevru Form3.
Nebo neotvirat Form3 jako dialog Formu2.
Já ale nechci Form2 zavřít. Chci aby po otevření Form3 zůstal Form2 zobrazený, ale neaktivní, zatímco Form1 byl stále aktivní.
Form3 otevri pomoci Show tzn. ne jako dialog a nasledne zadej v kodu form2
Enabled = false;
K řádku
Trojka.ShowDilaog();
se nedostanu. Chybou skončí ve Form2 už řádek
Form3 Trojka = new Form3();
Respektive chybu způsobí řádek
this.MujPrvek = new Programek.UserControl_Prvek();
v InitializeComponent(); ve Form3
Ja si vubec neprecetl puvodni dotaz a nevsiml jsem si, ze do toho mas zamotane vlakna. Takze podle me se snazis pristupovat napric vlakny k ruznym formum nebo neco. Dej sem cely kod. Formy jako takove by mely vzdy bezet ve stathread. Aktualizace dat v nich muzes delat z jinych vlaken pomoci Invoke (thread safe).
Do přílohy jsem vložil projekt testovací aplikace.
Krokoval jsem více do hloubky a chybu způsobují řádky
this.comboBox1.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.SuggestAppend;
this.comboBox1.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource;
v InitializeComponent(); ve Form3
Odkaz ke stažení testovací aplikace
https://drive.google.com/open?…
Nevim proc oteviras form ve novem vlakne. Pokud potrebujes provest nejake operace tak je nech provest ve vlakne a nasledne aktualizuj data ve Formu, ktery bezi v STAThread.
Form1
namespace Aplikace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form2 Dvojka = new Form2();
Dvojka.Show();
}
}
}
Form2
namespace Aplikace
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
try
{
Form3 Trojka = new Form3();
Trojka.FormClosed += Trojka_FormClosed;
Trojka.Show();
Enabled = false;
}
catch (Exception err)
{
MessageBox.Show(err.Message);
}
}
private void Trojka_FormClosed (object sender, FormClosedEventArgs e) {
Enabled = true;
}
}
}
Tvoje řešení v testovací aplikaci funguje.
Můj kód v ostré aplikaci je, bohužel, daleko složitější.
Upravil jsem testovací aplikaci tak, aby více odpovídala té ostré.
Nová testovací je zde
Cele tve reseni je nesikovne - hledej splash screen nebo napr
Nemuzu se ted podivat, v jakem stavu to ted mas, ale:
vyhod to
System.Threading.Tasks.Task.Run(() =>
nema to tam co delat.
Veskery UI nech v hlavnim vlakne a pokud potrebujes nejakou dele trvajici akci, tak az tu hod do jineho vlakna.
Pokud otviras pres ShowDialog(), tak tim to puvodni okno zablokujes, nez se to nove otevreny zavre, pokud nejaky okno chce mit pristupny, tak ty novy musis otevirat pres Show().
O co presne se pokousis?
Díky za šikovnější řešení ve Form_Pracuji.
Nevíš ještě jak zařídit, aby se animovaný gif vložený do tohoto
formuláře v průběhu provádění akce pohyboval?
Pokouším se o následující:
Form1 funguje jako portál, ze kterého se otevírají jednotlivé seznamy
záznamů, (např. Form2).
Je potřeba aby šlo otevřít více seznamů najednou i jeden seznam
vícekrát.
U každého otevřeného seznamu záznamů je možné otevřít konkrétní
záznam v novém formuláři (Form3).
Pokud se otevře konkrétní záznam (Form3) musí se deaktivovoat seznam
záznamů (Form2), ale ostatní seznamy záznamů (Form2) i hlavní portál
(Form1) musí zůstat aktivní).
Doufám, že je to srozumitelné.
Myslím, že toto nejde. Pokud otevřeš okno jako dialog, deaktivují se
tím všechna okna, neb dialog je vždy navrchu.
Řešení vidím v tom, že bys to okno, které chceš mít "deaktivované"
normálně skryl. Z form2 otevřeš form3, instanci form2 předáš do
konstruktoru formu3 a ve form3 jen skryješ form2.
Pak samozřejmě můžeš při zavírání form3 opět "zviditelnit" form2, nebo v něm provést nějakou jinou událost...
Form1.cs
private void button1_Click(object sender,EventArgs e)
{
new Form2().Show();
}
Form2.cs
private void button1_Click(object sender,EventArgs e)
{
Form3 f = new Form3();
this.Enabled=false;
f.FormClosed+=F3Closure;
f.Show();
}
void F3Closure(object sender,EventArgs e)
{
((Form)sender).FormClosed-=F3Closure;
this.Enabled=true;
}
Příště googluj, většinu problémů už vyřešili jiní.
Díky to zabralo
Zobrazeno 20 zpráv z 20.