Щелкните правой кнопкой мыши с подсказками слов (Hunspell) - PullRequest
0 голосов
/ 16 января 2019

У меня есть richtextbox и ContextMenuStrip, которые вырезали, копировали, вставляли и выбирали все, что все они работают без проблем, но теперь я попытался добавить предложение слов, например, если пользователь выбирает слово и щелкает правой кнопкой мыши на richtextbox, он должен показать его \ ее:

  • слово предложение
  • слово предложение
  • слово предложение
  • ... и т.д.
  • "Разрыв строки"
  • вырезано
  • Копирование
  • Прошлое
  • "Разрыв строки"
  • Выбрать все

так и должно быть, но проблема в том, что список предложений постоянно дублируется при каждом щелчке правой кнопкой мыши (после того, как я выбрал слово)

вот код:

ContextMenuStrip cms = new ContextMenuStrip { ShowImageMargin = true };

public void AddContextMenu(RichTextBox rtb)
    {
       if (rtb.ContextMenuStrip == null)
        {
            ToolStripMenuItem tsmiCut = new ToolStripMenuItem("Cut");
            tsmiCut.Image = msg.Properties.Resources.cut;
            tsmiCut.Click += (sender, e) => rtb.Cut();
            cms.Items.Add(tsmiCut);
            ToolStripMenuItem tsmiCopy = new ToolStripMenuItem("Copy");
            tsmiCopy.Image = msg.Properties.Resources.copy;
            tsmiCopy.Click += (sender, e) => rtb.Copy();
            cms.Items.Add(tsmiCopy);
            ToolStripMenuItem tsmiPaste = new ToolStripMenuItem("Paste");
            tsmiPaste.Image = msg.Properties.Resources.paste;
            tsmiPaste.Click += (sender, e) => rtb.Paste();
            cms.Items.Add(tsmiPaste);

            cms.Items.Add("-");
            ToolStripMenuItem sALL = new ToolStripMenuItem("Select All");
            sALL.Image = msg.Properties.Resources.select_all;
            sALL.Click += (sender, e) => rtb.SelectAll();
            cms.Items.Add(sALL);
            rtb.ContextMenuStrip = cms;
        }
    }

private void richTextBox_MouseDown(object sender, MouseEventArgs e)
    {
        Hunspell hunspell = new Hunspell("en_US.aff", "en_US.dic");
        hunspell.Spell(richTextBox.SelectedText);
        List<string> suggestions = hunspell.Suggest(richTextBox.SelectedText);

        ToolStripSeparator line = new ToolStripSeparator();
        AddContextMenu(richTextBox);


        if (e.Button == MouseButtons.Right)
        {
            foreach (string suggestion in suggestions)
            {
                ToolStripMenuItem sugg = new ToolStripMenuItem(suggestion);
                if (cms.Items.Contains(sugg))
                {
                    cms.Items.Remove(sugg);
                }
                else
                {
                    cms.Items.Add(sugg);
                }
            }
        }

    }

1 Ответ

0 голосов
/ 16 января 2019

Вам нужен контракт, чтобы различать пункты меню предложений и остальные пункты меню, затем при добавлении предложений сначала удалите существующие пункты предложений, а затем добавьте новые элементы.

Здесь в качестве примера я использую Tag свойство ToolStripMenuItem в качестве контракта, и все элементы строки меню, имеющие suggestion в своем теге, рассматриваются как рекомендации:

public void Suggest(List<string> words, ContextMenuStrip menu)
{
    string suggestion = "suggestion";
    menu.Items.Cast<ToolStripItem>().Where(x => x.Tag == (object)suggestion)
        .ToList().ForEach(x => menu.Items.Remove(x));

    words.ToList().ForEach(x =>
    {
        var item = new ToolStripMenuItem(x);
        item.Tag = suggestion;
        item.Click += (s, e) => MessageBox.Show(x);
        menu.Items.Insert(0, item);
    });
}

И как употребление, для одного слова:

Suggest(new List<string> { "something", "something else" }, contextMenuStrip1);

Для другого слова:

Suggest(new List<string> { "another", "another one" }, contextMenuStrip1);
...