NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

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.

Aktivity
Avatar
David Moškoř:28.3.2017 17:32

Dobrý den dělám si vlatsní textový editor. Vytvořil jsem si zde i položku najít, která mi fungovala v pohodě, Ale když jsem zkoušel nahradit tak už mi to nefungovalo. Vždy když se měl zobrazit MessageBox, tak se program jen tak minimalizoval a MessageBox se ukázal ale program se musel zase maximalizovat. Nevíte čím to je? Nebo když mám označený nějaký text a otevře se mi MessageBox tak se mi odznačí. Podle mne oznaceny zustane ale jen v pozadí protože, když message box zavřu tak se zase označí. Nešlo by nějak udělat aby se program neminimalizoval, a aby text zůstal označený? Předem děkuji za odpověď.
Kód zde:

public partial class Nahrad : Form
  {
      public Nahrad()
      {
          InitializeComponent();
      }
      private void vyraz_TextChanged(object sender, EventArgs e)
      {
          if (vyraz.Text != string.Empty)
          {
              nahrad_button.Enabled = true;
          }
          else
          {
              nahrad_button.Enabled = false;
          }
      }

      private void close_Click(object sender, EventArgs e)
      {
          Dispose();
      }
      public static string Vyraz = null;
      public static bool Velikost;
      public static bool WholeWords;
      public static bool Potvrdit;
      public static string Nahradit;
      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);
      }
      static bool znovu = false;
      static bool konec = false;
      public static int index = Form1.richTextBox1.SelectionStart;
      public static void hledam(string vyraz, string za, bool pismena, bool celaslova, bool
          potvrd)
      {
          // mám to udělané takhle divně protože když je RichTextBoxFinds.None a dojede to nakonec tak to nevrátí -1
          // ale pokračuje to zase od začátku :-(
          while (true)
          {
              if (index != -1)
              {
                  if ((celaslova == true) && (pismena == false))
                  {
                      index = Form1.richTextBox1.Find(vyraz, index, RichTextBoxFinds.WholeWord);
                  }
                  else if ((celaslova == false) && (pismena == true))
                  {
                      index = Form1.richTextBox1.Find(vyraz, index, RichTextBoxFinds.MatchCase);
                  }
                  else if ((celaslova == true) && (pismena == true))
                  {
                      index = Form1.richTextBox1.Find(vyraz, index, RichTextBoxFinds.MatchCase | RichTextBoxFinds.WholeWord);
                  }
                  else
                  {
                      index = Form1.richTextBox1.Find(vyraz, index, RichTextBoxFinds.None);
                      if (index == Form1.richTextBox1.TextLength - vyraz.Length)
                      {
                          konec = true;
                      }
                  }
              }
              if (index != -1)
              {
                  Form1.richTextBox1.SelectionStart = index;
                  Form1.richTextBox1.SelectionLength = vyraz.Length;
                  index += 1;
                  znovu = false;
                  DialogResult msg;
                  if (potvrd)
                  {
                      msg = MessageBox.Show("Chcete nahradit řetězec: '" + vyraz + "' => '" + za + "'", "Nahradit", MessageBoxButtons.YesNoCancel);
                  }
                  else
                  {
                      msg = DialogResult.Yes;
                  }
                  if (msg == DialogResult.Yes)
                  {
                      Form1.richTextBox1.SelectedText = za;
                  }
                  else if (msg == DialogResult.Cancel)
                  {
                      break;
                  }
                  if (konec)
                  {
                      index = -1;
                  }
              }
              else
              {
                  if (!znovu)
                  {
                      if (MessageBox.Show("Žádné další výsledky nebyly nalezeny, chcete hledat od začátku?", "Konec", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.Yes)
                      {
                          konec = false;
                          index = 0;
                          znovu = true;
                          hledam(vyraz, za, pismena, celaslova, potvrd);
                      }
                      else
                      {
                          break;
                      }
                  }
                  else
                  {
                      MessageBox.Show("Nic nenalezeno!", "Konec", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                      break;
                  }
              }
          }
          znovu = false;
      }

      private void vyraz_KeyDown(object sender, KeyEventArgs e)
      {
          if (e.KeyCode == Keys.Enter)
          {
              e.Handled = true;
              nahrad_button.PerformClick();
          }
          else if (e.KeyCode == Keys.F3)
          {
              nahrad_button.PerformClick();
          }
      }

      private void najdi_Load(object sender, EventArgs e)
      {
          if (Vyraz != null)
          {
              vyraz.Text = Vyraz;
              pismena.Checked = Velikost;
              celaslova.Checked = WholeWords;
              nahradit.Text = Nahradit;
              potvrd.Checked = Potvrdit;
          }
      }
  }
Odpovědět
28.3.2017 17:32
Život je příliš krátký na to, abyste vymýšleli smysluplné názvy proměnných...
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na David Moškoř
gcx11:28.3.2017 18:15

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);
 
Nahoru Odpovědět
28.3.2017 18:15
Avatar
David Moškoř:28.3.2017 18:16

Kdybych to dal naopak tak se to okno nezavře

Nahoru Odpovědět
28.3.2017 18:16
Život je příliš krátký na to, abyste vymýšleli smysluplné názvy proměnných...
Avatar
Odpovídá na David Moškoř
Michal Štěpánek:28.3.2017 18:53

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...

Editováno 28.3.2017 18:54
Nahoru Odpovědět
28.3.2017 18:53
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
gcx11
Tvůrce
Avatar
Odpovídá na David Moškoř
gcx11:28.3.2017 19:06

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?

 
Nahoru Odpovědět
28.3.2017 19:06
Avatar
Odpovídá na Michal Štěpánek
Marian Benčat:28.3.2017 19:06

IMHO 95% C# vývojářů - a to i seniorů neví úplně správně, co dělá Dispose ;-)

Nahoru Odpovědět
28.3.2017 19:06
Totalitní admini..
Avatar
HONZ4
Člen
Avatar
HONZ4:28.3.2017 19:20

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..

 
Nahoru Odpovědět
28.3.2017 19:20
Avatar
HONZ4
Člen
Avatar
Odpovídá na Marian Benčat
HONZ4:28.3.2017 19:27

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.

Editováno 28.3.2017 19:29
 
Nahoru Odpovědět
28.3.2017 19:27
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na Marian Benčat
Petr Čech:28.3.2017 19:33

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

Nahoru Odpovědět
28.3.2017 19:33
the cake is a lie
Avatar
Petr Čech
Tvůrce
Avatar
Odpovídá na Marian Benčat
Petr Čech:29.3.2017 14:13

Myslím, že to je ono :D

Nahoru Odpovědět
29.3.2017 14:13
the cake is a lie
Avatar
Odpovídá na HONZ4
David Moškoř:31.3.2017 17:03

Děkuji změny provedu. Pravda, že to dělám zbytečně složitě

Nahoru Odpovědět
31.3.2017 17:03
Život je příliš krátký na to, abyste vymýšleli smysluplné názvy proměnných...
Avatar
David Moškoř:31.3.2017 17:05

Dispose() jsem umístil až nakonec ale pořád nefunguje...

Nahoru Odpovědět
31.3.2017 17:05
Život je příliš krátký na to, abyste vymýšleli smysluplné názvy proměnných...
Avatar
David Moškoř:31.3.2017 17:21

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()?

Nahoru Odpovědět
31.3.2017 17:21
Život je příliš krátký na to, abyste vymýšleli smysluplné názvy proměnných...
Avatar
HONZ4
Člen
Avatar
Odpovídá na David Moškoř
HONZ4:31.3.2017 18:35

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();
 }
 
Nahoru Odpovědět
31.3.2017 18:35
Avatar
HONZ4
Člen
Avatar
HONZ4:31.3.2017 19:20

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í.

Editováno 31.3.2017 19:22
 
Nahoru Odpovědět
31.3.2017 19:20
Avatar
HONZ4
Člen
Avatar
HONZ4:31.3.2017 21:40

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 :)

Editováno 31.3.2017 21:41
Akceptované řešení
+20 Zkušeností
+2,50 Kč
Řešení problému
 
Nahoru Odpovědět
31.3.2017 21:40
Avatar
ostrozan
Tvůrce
Avatar
ostrozan:1.4.2017 7:15

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

Editováno 1.4.2017 7:17
 
Nahoru Odpovědět
1.4.2017 7:15
Avatar
David Moškoř:8.4.2017 15:28

Děkuji všem za rady nakonec jsem to vyřešil.

HONZ4:

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?

Nahoru Odpovědět
8.4.2017 15:28
Život je příliš krátký na to, abyste vymýšleli smysluplné názvy proměnných...
Avatar
Jan Vargovský
Tvůrce
Avatar
Odpovídá na David Moškoř
Jan Vargovský:8.4.2017 16:30

Můžeš si to přepsat a uvidíš co je čitelnější :)

 
Nahoru Odpovědět
8.4.2017 16:30
Avatar
HONZ4
Člen
Avatar
Odpovídá na David Moškoř
HONZ4:8.4.2017 19:48

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í...

 
Nahoru Odpovědět
8.4.2017 19:48
Avatar
Odpovídá na HONZ4
David Moškoř:9.4.2017 17:27

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ší.

Editováno 9.4.2017 17:28
Nahoru Odpovědět
9.4.2017 17:27
Život je příliš krátký na to, abyste vymýšleli smysluplné názvy proměnných...
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 22 zpráv z 22.