WPF 富文本框中的拼写检查器

本文关键字:检查 文本 WPF | 更新日期: 2023-09-27 18:30:51

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

主例程循环遍历富文本框中的文本,直到发现拼写错误。然后,用户可以选择通过单击调用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();
    }

}

}

WPF 富文本框中的拼写检查器

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

在按钮单击事件中,设置按钮的命令和参数,然后执行拼写检查词。但是实际命令是在代码离开方法之后执行的。这意味着,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();
    }

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