Diskuze: Problém s MessageBoxem
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 22 zpráv z 22.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Ahoj, jsi si jistý, že je tahle metoda dobře? Zavoláš Dispose() a pak něco děláš.
private void najitdal_Click(object sender, EventArgs e)
{
bool Pismena = false;
bool Celaslova = false;
bool Potvrd = true;
if (pismena.Checked == true)
{
Pismena = true;
}
if (celaslova.Checked == true)
{
Celaslova = true;
}
if (potvrd.Checked == false)
{
Potvrd = false;
}
Vyraz = vyraz.Text;
Velikost = Pismena;
WholeWords = Celaslova;
Potvrdit = Potvrd;
Nahradit = nahradit.Text;
Dispose();
hledam(Vyraz, Nahradit,Pismena, Celaslova, Potvrd);
Kdybych to dal naopak tak se to okno nezavře
A jsi si jistý, že správně chápeš, co dělá "Dispose"? Nemůžeš přeci zavřít dveře a pak skrz ně chtít procházet...
Ještě k tomu, proč to začne zase od začátku, jak píšeš v komentáři jedné metody. Chápeš, že se Ti tam tvoří rekurze?
IMHO 95% C# vývojářů - a to i seniorů neví úplně správně, co dělá Dispose
pár věcí co jsem postřehnul:
místo:
if (vyraz.Text != string.Empty)
{
nahrad_button.Enabled = true;
}
else
{
nahrad_button.Enabled = false;
}
stačí:
nahrad_button.Enabled = (vyraz.TextLength > 0);
místo:
bool Pismena = false;
if (pismena.Checked == true)
{
Pismena = true;
}
Velikost = Pismena;
stačí:
Velikost = pismena.Checked;
apd. pak se to bude i lépe číst..
já to mám zažité tak, že označím objekt nepotřebný (uvolním jej) v něm se pak provedou akce které se při dispose mají provést, a pak GC jej může smazat.
Dá se na to přijít potom, co se pokusíš o vlastní implementaci tak, aby byla v souladu s vyčerpávajícím manuálem od Microsoftu
Děkuji změny provedu. Pravda, že to dělám zbytečně složitě
Dispose() jsem umístil až nakonec ale pořád nefunguje...
Aha zjistil jsem, že byla chyba ve stavění projektu. Už mi to funguje děkuji jenom mám ještě dotaz jestli by nešlo udělat, že se to okno zavře a až pak začne funkce hledam(). Neexistuje na to něco jako dispose()?
Možná jsem jediný, kdo nechápe jak chceš aby to fungovalo.
Ale pokud chceš zobrazit formulář jako dialog a pak něco vykonat tak takto:
Form2 NejakyForm = new Form2();
if(NejakyForm.ShowDialog() == DialogResult.OK)
{
DelejNeco();
}
Nevím, jestli si mou ukázku můžeš vzít jako příklad, ale takhle nějak bych to řešil já:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Prepsat_Click(object sender, EventArgs e)
{
richTextBox1.FindAndReplace(richTextBox1.SelectionStart, textboxNajit.Text,
textboxPrepsatNa.Text, checkboxVelkaMala.Checked,
checkboxCelaSlova.Checked,
checkboxPotvrzovani.Checked);
}
}
public static class RichTextBoxEx
{
/// <summary>
///
/// </summary>
/// <param name="re"></param>
/// <param name="start_position">Hledat od pozice (>= 0)</param>
/// <param name="from">Hledaný text</param>
/// <param name="to">Přepsat na</param>
/// <param name="caseSensitive">Rozlišování velkých a malých písmen</param>
/// <param name="holeWord">Celá slova</param>
/// <param name="confirm">Potvrzovat přepis</param>
public static void FindAndReplace(this RichTextBox re, int start_position, string from, string to, bool caseSensitive, bool holeWord, bool confirm)
{
if(re.TextLength == 0) return;
RichTextBoxFinds rfinds = RichTextBoxFinds.None;
if(caseSensitive) rfinds |= RichTextBoxFinds.MatchCase;
if(holeWord) rfinds |= RichTextBoxFinds.WholeWord;
int start = start_position;
bool stop = false;
while (!stop && start > -1)
{
start = re.Find(from, start, rfinds);
if (start > -1)
{
if(confirm)
{
string msg = "Chcete nahradit řetězec: '" + from + "' => '" + to + "'";
switch(MessageBox.Show(msg, "Nahradit?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question))
{
case DialogResult.No: start++; goto next;
case DialogResult.Yes: goto replace;
default: stop = true; break;
}
}
replace:
re.SelectedText = to; start += to.Length;
next:
if (start >= re.TextLength)
{
MessageBox.Show("Hledání dokončeno!", "Konec", MessageBoxButtons.OK, MessageBoxIcon.Information);
break;
}
}
else
{
if (start_position == 0) MessageBox.Show("Nic nenalezeno!", "Konec", MessageBoxButtons.OK, MessageBoxIcon.Warning);
else
{
if (DialogResult.OK == MessageBox.Show("Chcete hledat znovu od začátku textu?",
"Hledání dokončeno",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question))
{
start = 0;
start_position = 0;
}
else break;
}
}
}
}
}
ale až na ty názvy kontrolek, ty jsem takhle pojmenoval, jen pro to ať máš představu co mám na formuláři.
Toto je jen ukázka jak se dá řešit ten přepis pomocí rozšíření.
předchozí kód jsem psal narychlo, ani jsem to skoro netestoval, až teď
jsem zjistil, že nefunguje moc dobře.
Tady je oprava:
public static class RichTextBoxEx
{
/// <summary>
/// nahrazení textu s nastavením a dialogy
/// </summary>
/// <param name="re"></param>
/// <param name="start_position">Hledat od pozice (>= 0)</param>
/// <param name="from">Hledaný text</param>
/// <param name="to">Přepsat na</param>
/// <param name="caseSensitive">Rozlišování velkých a malých písmen</param>
/// <param name="holeWord">Celá slova</param>
/// <param name="confirm">Potvrzovat přepis</param>
public static void FindAndReplace(this RichTextBox re, int start_position, string from, string to, bool caseSensitive, bool holeWord, bool confirm)
{
if (re.TextLength == 0) return;
RichTextBoxFinds rfinds = RichTextBoxFinds.None;
if (caseSensitive) rfinds |= RichTextBoxFinds.MatchCase;
if (holeWord) rfinds |= RichTextBoxFinds.WholeWord;
int start = start_position;
bool stop = false;
bool any = false;
while (true)
{
start = re.Find(from, start, rfinds);
if(start > -1)
{
if (confirm)
{
string msg = "Chcete nahradit řetězec: '" + from + "' => '" + to + "'";
switch (MessageBox.Show(msg, "Nahradit?", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question))
{
case DialogResult.No: start++; goto end;
case DialogResult.Yes: goto replace;
default: stop = true; break;
}
}
if (stop) return;
replace:
re.SelectedText = to;
start += to.Length;
any = true;
}
end:
if(start >=re.TextLength || start == -1)
{
if (start_position == 0)
{
MessageBox.Show((any) ? "Dokončeno." : "Nic nenalezeno!", "Konec", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
else
{
if (DialogResult.OK == MessageBox.Show("Chcete hledat znovu od začátku textu?",
"Hledání dokončeno",
MessageBoxButtons.OKCancel,
MessageBoxIcon.Question))
{
start = 0;
start_position = 0;
}
else break;
}
}
}
}
}
teď už je to snad OK
Pokud by sis chtěl udělat opravdový editor s formátováním, vkládáním
obrázků, grafů - ne jen další "notepad" - pak inspiraci najdeš "tady ":http://www.wpf-tutorial.com/…text-editor/
Znamená to ovšem přechod na WPF
Děkuji všem za rady nakonec jsem to vyřešil.
předchozí kód jsem psal narychlo, ani jsem to skoro netestoval, až teď jsem zjistil, že nefunguje moc dobře. Tady je oprava:
Je dodrý nápad používat goto?
Podle mě je to lepší, než mít duplicitu v kódu, nebo volat nějakou
další metodu. Sám moc goto nepoužívám (kvůli přehlednosti
kódu), ale někdy se stane, že je kód s goto přehlednější.
Ale pokud chceš, můžeš vymyslet přehlednější a kvalitnější
řešení...
Vyřešil jsem to nějak takhle. Zavolal jsem Dispose() a pak jak se to zavřelo tak jsem ve Form1 zavolal metodu hledam(). S označením jsem si už poradil pomocí Selection color. Kód jsem podle vašich rad trochu upravil, aby byl přehlednější.
Zobrazeno 22 zpráv z 22.