【问题标题】:Spell checker in a WPF RichTextBoxWPF RichTextBox 中的拼写检查器
【发布时间】:2016-07-30 16:42:24
【问题描述】:

我创建了一个 RichTextBox 文本编辑器作为 c# Form 应用程序解决方案。我已在此解决方案中添加了一个 WPF 应用程序来充当拼写检查器。基本上,当我运行拼写检查器时,RichTextBox 的内容被复制到 WPF 应用程序中的 WPF RichTextBox,我已将其配置为看起来像拼写检查对话框。我包含了一个ListBox,它显示拼写错误建议和按钮,如果单击其中一个建议,用户可以忽略错误或更改。

主例程循环遍历 RichTextBox 中的文本,直到发现拼写错误。然后,用户可以选择通过单击调用EditingCommands.IgnoreSpellingError 的按钮来忽略或通过单击调用EditingCommands.CorrectSpellingError 的按钮进行更改。目前我正在使用另一个按钮然后重新循环通过RichTextBox 以查找下一个拼写错误。

理想情况下,我希望发生的情况是,例如,当单击忽略按钮时,会调用 EditingCommands.IgnoreSpellingError,然后立即运行主例程,如下所示:

    private void button3_Click(object sender, RoutedEventArgs e)
    {
        button3.Command = EditingCommands.IgnoreSpellingError;
        button3.CommandTarget = richTextBox1;
        spellCheckWords();
    }

但是,这不起作用,因为RichTextBox 似乎与拼写检查器不同步。好像表单或RichTextBox 没有正确刷新。只是为了重新迭代,如果我使用单独的按钮重新运行主程序,那么它可以正常工作。

完整的代码如下。

任何帮助将不胜感激。

using System;
using System.Threading;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO;

namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{

    public MainWindow()
    {
        InitializeComponent();
        richTextBox1.SpellCheck.IsEnabled = true;
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        richTextBox1.Paste();
        richTextBox1.ContextMenu = GetContextMenu();
        spellCheckWords();
    }

    private static int chrPos = 0;

    private void spellCheckWords()
    {
        SpellingError spellingError;
        TextRange spellErrorRange;
        TextPointer start_pointer, end_pointer;

        richTextBox1.ContextMenu = GetContextMenu();
        richTextBox1.SelectAll();
        int txtLen = richTextBox1.Selection.Text.Length;
        bool noSpellingErrors = true; ;

        for (int i = chrPos; i < txtLen; i++)
        {
            start_pointer = richTextBox1.Document.ContentStart.GetNextInsertionPosition
                (LogicalDirection.Forward).GetPositionAtOffset(i, LogicalDirection.Forward);

            spellingError = richTextBox1.GetSpellingError(start_pointer);
            if (spellingError != null)
            {
                 spellErrorRange = richTextBox1.GetSpellingErrorRange(start_pointer);
                int errRange = spellErrorRange.Text.Length;

                textBox1.Text = spellErrorRange.Text;

                noSpellingErrors = true;
                string textRun = start_pointer.GetTextInRun(LogicalDirection.Forward);
                string trimmedString = string.Empty;
                end_pointer = richTextBox1.Document.ContentStart.GetNextInsertionPosition
                    (LogicalDirection.Forward).GetPositionAtOffset(i + errRange, LogicalDirection.Forward);
                richTextBox1.Selection.Select(start_pointer, start_pointer);
                richTextBox1.Focus();

                Rect screenPos = richTextBox1.Selection.Start.GetCharacterRect(LogicalDirection.Forward);
                double offset = screenPos.Top + richTextBox1.VerticalOffset;
                richTextBox1.ScrollToVerticalOffset(offset - richTextBox1.ActualHeight / 2);

                listBox1.Items.Clear();
                foreach (string str in spellingError.Suggestions)
                {
                    listBox1.Items.Add(str);
                }
                //chrPos = i + errRange + 1;
                return;
            }
        }
        if (noSpellingErrors == true) 
        { 
            textBox1.Text = "No spelling Errors";
            listBox1.Items.Clear();
            button2.IsEnabled = false;
            button3.IsEnabled = false;
            button4.IsEnabled = false;
            button6.IsEnabled = false;
        }
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        richTextBox1.SelectAll();
        richTextBox1.Copy();
        richTextBox1.Document.Blocks.Clear();
        richTextBox1.SpellCheck.IsEnabled = false;
        this.Close();
    }

    private ContextMenu GetContextMenu()
    {
        return null;
    }

    private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (listBox1.SelectedItem != null)
            textBox1.Text = listBox1.SelectedItem.ToString();
    }

    private void button2_Click(object sender, RoutedEventArgs e)
    {
        button2.Command = EditingCommands.CorrectSpellingError;
        button2.CommandParameter = textBox1.Text;
        button2.CommandTarget = richTextBox1;
        spellCheckWords();
    }

    private void button3_Click(object sender, RoutedEventArgs e)
    {
        button3.Command = EditingCommands.IgnoreSpellingError;
        button3.CommandTarget = richTextBox1;
        spellCheckWords();
    }

    private void button4_Click(object sender, RoutedEventArgs e)
    {
        spellCheckWords();
    }


}

}

【问题讨论】:

  • 您能否详细解释一下您的问题?
  • 嗨 Aviral,我不知道如何进一步解释这一点。这就是我包含代码的原因之一。如果你能告诉我你还需要知道什么,我会回复。请记住,我是 c# 的相对新手。大卫
  • 只有一件事,RichTextBox seems to go out of synchronisation with the spell checker 是什么意思,到底发生了什么?

标签: c# wpf richtextbox


【解决方案1】:

过了一会儿,我遇到了你的问题^^(我认为)并且很容易解决。

在您的Button-Click-events 中,您设置按钮的命令和参数,然后执行spellCheckWords。但是实际的命令是在代码离开方法之后执行的。 这意味着,spellCheckWords() 在 IgnoreSpellingError 之前执行。

将您的代码更改为:

        private void button2_Click(object sender, RoutedEventArgs e)
    {
        EditingCommands.CorrectSpellingError.Execute(textBox1.Text, richTextBox1);
        spellCheckWords();
    }

    private void button3_Click(object sender, RoutedEventArgs e)
    {
        EditingCommands.IgnoreSpellingError.Execute(null, richTextBox1);
        spellCheckWords();
    }

这将首先执行命令,然后再次进行拼写检查。

【讨论】:

  • 辛苦了,非常感谢。出于兴趣,出了什么问题,这是如何解决的?
  • 当你设置 button.Command 你实际上并没有执行你为以后设置的命令。然后执行 spellCheckWords 并在 Click-Event 完成后 Button 识别命令并执行它。
  • 嗨,Uwe,我现在意识到这只是部分工作。忽略按钮可以正常工作,但正确的按钮不能。它不会将 RichTextBox 上的文本更改为正确的拼写。
  • 它适用于我的示例应用程序。 RichTextBox 中的文本将替换为 textBox1 中的文本。您是否更改了 TextBox 中的文本?还是你想要其他地方的文字?
  • 嗨 Uwe,让它工作,没有发现 textBox1.text 包含在 CorrectSpellingError.Execute 部分中。我的错。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多