【问题标题】:Trying to use the C# SpellCheck class尝试使用 C# SpellCheck 类
【发布时间】:2010-10-26 14:37:15
【问题描述】:

我正在尝试使用 C# 提供的 SpellCheck 类(在 PresentationFramework.dll 中)。 但是,我在尝试将拼写绑定到我的文本框时遇到了问题:

SpellCheck.SetIsEnabled(txtWhatever, true);

问题是我的 txtWhatever 是 System.Windows.Forms 类型,而这个函数正在寻找的参数是 System.Windows.Controls,简单的转换失败了。 我也试图让我的文本框成为这种类型,但是......做不到。 有谁知道如何使用这个 SpellCheck 对象? (MSDN 没那么有用……)

谢谢

【问题讨论】:

    标签: c# .net winforms textbox spell-checking


    【解决方案1】:

    您必须使用 WPF 文本框来进行拼写检查。您可以使用 ElementHost 控件将一个嵌入到 Windows 窗体窗体中。它的工作方式与 UserControl 非常相似。这是一个可以直接从工具箱中删除的控件。要开始,您需要 Project + Add Reference 并选择 WindowsFormsIntegration、System.Design 和 WPF 程序集 PresentationCore、PresentationFramework 和 WindowsBase。

    向您的项目添加一个新类并粘贴如下所示的代码。编译。将 SpellBox 控件从工具箱顶部拖放到窗体上。它支持 TextChanged 事件以及 Multiline 和 WordWrap 属性。字体有一个令人烦恼的问题,没有简单的方法可以将 WF 字体映射到 WPF 字体属性。最简单的解决方法是将表单的字体设置为“Segoe UI”,这是 WPF 的默认值。

    using System;
    using System.ComponentModel;
    using System.ComponentModel.Design.Serialization;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Forms.Integration;
    using System.Windows.Forms.Design;
    
    [Designer(typeof(ControlDesigner))]
    //[DesignerSerializer("System.Windows.Forms.Design.ControlCodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.ComponentModel.Design.Serialization.CodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    class SpellBox : ElementHost {
        public SpellBox() {
            box = new TextBox();
            base.Child = box;
            box.TextChanged += (s, e) => OnTextChanged(EventArgs.Empty);
            box.SpellCheck.IsEnabled = true;
            box.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
            this.Size = new System.Drawing.Size(100, 20);
        }
        public override string Text {
            get { return box.Text; }
            set { box.Text = value; }
        }
        [DefaultValue(false)]
        public bool Multiline {
            get { return box.AcceptsReturn; }
            set { box.AcceptsReturn = value; }
        }
        [DefaultValue(false)]
        public bool WordWrap {
            get { return box.TextWrapping != TextWrapping.NoWrap; }
            set { box.TextWrapping = value ? TextWrapping.Wrap : TextWrapping.NoWrap; }
        }
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public new System.Windows.UIElement Child {
            get { return base.Child; }
            set { /* Do nothing to solve a problem with the serializer !! */ }
        }
        private TextBox box;
    }
    

    应大众需求,此代码的 VB.NET 版本避免了 lambda:

    Imports System
    Imports System.ComponentModel
    Imports System.ComponentModel.Design.Serialization
    Imports System.Windows
    Imports System.Windows.Controls
    Imports System.Windows.Forms.Integration
    Imports System.Windows.Forms.Design
    
    <Designer(GetType(ControlDesigner))> _
    Class SpellBox
        Inherits ElementHost
    
        Public Sub New()
            box = New TextBox()
            MyBase.Child = box
            AddHandler box.TextChanged, AddressOf box_TextChanged
            box.SpellCheck.IsEnabled = True
            box.VerticalScrollBarVisibility = ScrollBarVisibility.Auto
            Me.Size = New System.Drawing.Size(100, 20)
        End Sub
    
        Private Sub box_TextChanged(ByVal sender As Object, ByVal e As EventArgs)
            OnTextChanged(EventArgs.Empty)
        End Sub
    
        Public Overrides Property Text() As String
            Get
                Return box.Text
            End Get
            Set(ByVal value As String)
                box.Text = value
            End Set
        End Property
    
        <DefaultValue(False)> _
        Public Property MultiLine() As Boolean
            Get
                Return box.AcceptsReturn
            End Get
            Set(ByVal value As Boolean)
                box.AcceptsReturn = value
            End Set
        End Property
    
        <DefaultValue(False)> _
        Public Property WordWrap() As Boolean
            Get
                Return box.TextWrapping <> TextWrapping.NoWrap
            End Get
            Set(ByVal value As Boolean)
                If value Then
                    box.TextWrapping = TextWrapping.Wrap
                Else
                    box.TextWrapping = TextWrapping.NoWrap
                End If
            End Set
        End Property
    
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _
        Public Shadows Property Child() As System.Windows.UIElement
            Get
                Return MyBase.Child
            End Get
            Set(ByVal value As System.Windows.UIElement)
                '' Do nothing to solve a problem with the serializer !!
            End Set
        End Property
        Private box As TextBox
    End Class
    

    【讨论】:

    • 我正在尝试实施您的解决方案:代码的 (s,e) 部分是什么意思?因为我得到了一个编译器错误?
    • 这对我不起作用,我不知道为什么。错误的词没有下划线。起初,编译器声称未找到程序集引用,但只是添加了 System.Xaml 引用已解决。但咒语仍然对我不起作用:prntscr.com/6rvwwk 我错过了什么?当然textBox 是你的SpellBox
    • 好的,我搞定了。 :) 我明确设置了语言:box.Language = System.Windows.Markup.XmlLanguage.GetLanguage("en-US");。您还需要安装 .NET 语言包(但我已经安装了)。我不确定,但这个问题可能是因为英语不是我操作系统的语言。它工作:prntscr.com/6rw50x
    • @Hans 很好的例子,非常感谢。只是一个简单的问题,我们是否可以将自定义单词添加到您提供的示例的字典中?
    • @HansPassant- 想通了。我需要动态地将事件添加到我的表单中。感谢您的工作。
    【解决方案2】:

    您是否尝试过在您尝试进行拼写检查的实际 TextBox 上设置属性。例如

    txtWhatever.SpellCheck.IsEnabled = true;
    

    【讨论】:

    • 是的,我试过了。 System.Windows.Forms 可能没有这个属性。这正是我的问题...
    【解决方案3】:

    您正在尝试在 WinForms 应用程序上使用为 WPF 设计的拼写检查组件。它们不兼容。

    如果您想使用 .NET 提供的拼写检查,则必须使用 WPF 作为您的小部件系统。

    如果您想坚持使用 WinForms,则需要第三方拼写检查组件。

    【讨论】:

      【解决方案4】:

      可以看到基于 WPF 文本框的免费 .NET 拼写检查器,可以在客户端或服务器端使用 here。尽管您仍然需要将程序集包含到 Presentation 框架等中,但它会为您包装文本框。

      完全披露...由您真实撰写

      【讨论】:

        【解决方案5】:

        我需要在 winforms 中的文本框中添加背景颜色,以反映在设计器中选择的颜色:

        public override System.Drawing.Color BackColor
        {
            get
            {
                if (box == null) { return Color.White; }
                System.Windows.Media.Brush br = box.Background;
                byte a = ((System.Windows.Media.SolidColorBrush)(br)).Color.A;
                byte g = ((System.Windows.Media.SolidColorBrush)(br)).Color.G;
                byte r = ((System.Windows.Media.SolidColorBrush)(br)).Color.R;
                byte b = ((System.Windows.Media.SolidColorBrush)(br)).Color.B;
                return System.Drawing.Color.FromArgb((int)a, (int)r, (int)g, (int)b);
            }
            set 
            {
                box.Background = new System.Windows.Media.SolidColorBrush(System.Windows.Media.Color.FromArgb(value.A, value.R, value.G, value.B));
            }
        }
        

        【讨论】:

          【解决方案6】:

          如果要启用 TextChanged 事件,请编写如下代码。

          using System;
          using System.ComponentModel;
          using System.ComponentModel.Design.Serialization;
          using System.Windows;
          using System.Windows.Controls;
          using System.Windows.Forms.Integration;
          using System.Windows.Forms.Design;
          
          [Designer(typeof(ControlDesigner))]
          //[DesignerSerializer("System.Windows.Forms.Design.ControlCodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", "System.ComponentModel.Design.Serialization.CodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
          class SpellBox : ElementHost
          {    
              public SpellBox()
              {
                  box = new TextBox();
                  base.Child = box;
                  box.TextChanged += (s, e) => OnTextChanged(EventArgs.Empty);
                  box.SpellCheck.IsEnabled = true;
                  box.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
                  box.TextChanged += new System.Windows.Controls.TextChangedEventHandler(SpellBox_TextChanged);
                  this.Size = new System.Drawing.Size(100, 20);
              }
          
              [Browsable(true)]
              [Category("Action")]
              [Description("Invoked when Text Changes")]
              public new event EventHandler TextChanged;
              protected void SpellBox_TextChanged(object sender, EventArgs e)
              {        
                  if (this.TextChanged!=null)
                      this.TextChanged(this, e);
              }
              public override string Text
              {
                  get { return box.Text; }
                  set { box.Text = value; }
              }
              [DefaultValue(false)]
              public bool Multiline
              {
                  get { return box.AcceptsReturn; }
                  set { box.AcceptsReturn = value; }
              }
              [DefaultValue(false)]
              public bool WordWrap
              {
                  get { return box.TextWrapping != TextWrapping.NoWrap; }
                  set { box.TextWrapping = value ? TextWrapping.Wrap : TextWrapping.NoWrap; }
              }
              [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
              public new System.Windows.UIElement Child
              {
                  get { return base.Child; }
                  set { /* Do nothing to solve a problem with the serializer !! */ }
              }
              private TextBox box;
          }
          

          【讨论】:

            【解决方案7】:

            如何获取英语单词列表并将其复制到文本文件中。添加参考。然后使用 streamreader 类针对 textbox.text 分析列表。在文本文件中找不到的任何单词都可以设置为突出显示或显示在带有替换或忽略选项的对话框中。这是一个缺少许多步骤的霰弹枪建议,我已经进行了 2 个月的编程,但是....无论如何我都会尝试。我正在制作一个记事本项目(idreamincode.com 上的 rexpad)。希望这会有所帮助!

            【讨论】:

            • 这更像是一个评论而不是一个答案。您是否阅读了接受的答案?
            猜你喜欢
            • 1970-01-01
            • 2017-04-06
            • 1970-01-01
            • 2020-03-22
            • 1970-01-01
            • 2014-12-10
            • 1970-01-01
            • 2021-11-26
            • 1970-01-01
            相关资源
            最近更新 更多