【问题标题】:Detecting if IME (Input Method Editor) is active in Silverlight检测 IME(输入法编辑器)是否在 Silverlight 中处于活动状态
【发布时间】:2015-02-06 15:40:13
【问题描述】:

有谁知道我如何轻松检测 Windows 操作系统 IME(输入法编辑器)是否在 Silverlight 框架中处于活动状态。让我解释一下导致我出现问题的场景:

我遇到了一个问题,即使用中文(简体,中国)微软拼音会导致 CLR 异常。该场景是当 TextBox 正在处理其 TextChanged 事件时。例如:

  • 文本框不应接受字符,而只能接受数字。为了实现这一点,它正在处理其 TextChanged 事件,并且在该事件中,它通过将其 Text 属性逐个字符地反转为最后一个正确的输入来处理输入。在这种情况下,如果使用(中文(简体,中国)Microsoft 拼音)IME,则会抛出 FatalExecutionEngineError

在 WPF 中,可以通过使用 InputMethod.Current.ImeState 检查 IME 是否处于活动状态,通过不反转 TextChanged 事件中的文本来解决此问题。不幸的是,这在 Silverlight 框架中不可用,这就是我发布此问题的原因。

目前我唯一发现的是,我可以将 InputMethod 类的 IsInputMethodEnabled 属性设置为 TextBox 控件,以禁用所有 IME 输入,但这当然不仅会禁用不正确的输入,还会禁用正确的输入。

有人知道如何检测 IME 是否在 Silverlight 平台中使用/处于活动状态?谢谢。

【问题讨论】:

    标签: c# .net wpf silverlight


    【解决方案1】:

    我能够在 WPF 和 Silverlight 框架中解决该问题。该问题是由于在 IME 输入符号时处理 TextBox 文本导致 IME 本身更改其输入,看起来 Windows 操作系统没有妥善处理并导致 CLR 异常。

    我所做的是:

    在前面提到的 WPF 框架中,我使用静态 InputMethod.Current.ImeState 值来确定 IME 是否处于活动状态,如果它具有 On 值,我跳过了在其 TextChanged 事件中恢复 TextBox Text 属性。

    在 Silverlight 框架中,如果检测到 IME,我会使用 TextInputStart、TextInputUpdate 事件和本地私有字段的组合来存储。 TextInputUpdate 事件仅在 IME 处于活动状态并用作输入并且始终触发 TextInputStart 时才会触发。我所做的是:

    1. 创建了 bool IsImeActive = false;归档
    2. 挂钩到 TextBox 的 TextInputStart 事件
    3. 在该事件中,将 IsImeActive 字段设置为 False
    4. 挂钩到 TextBox 的 TextInputUpdate 事件
    5. 在这种情况下,将 IsImeActive 字段设置为 True
    6. 最后在 TextChanged 事件中添加一个检查 IsImeActive 字段的条件,如果为 False,则运行处理(反转)输入的逻辑。

    希望这有帮助。

    【讨论】:

      【解决方案2】:

      当某些 IME 处于活动状态时,我还会收到 FatalExecutionEngineError,错误代码 0x80131623

      我的解决方法:我可以通过

      获得 IME 事件
      TextCompositionManager.AddPreviewTextInputHandler(myTextbox, OnPreviewTextInput);
      TextCompositionManager.AddPreviewTextInputStartHandler(myTextbox, OnPreviewTextInputStart);
      TextCompositionManager.AddPreviewTextInputUpdateHandler(myTextbox, OnPreviewTextInputUpdate);
      
      private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
      {
          ImeFlag = false;
      }
      private void OnPreviewTextInputStart(object sender, TextCompositionEventArgs e)
      {
          ImeFlag = true;
      }
      private void OnPreviewTextInputUpdate(object sender, TextCompositionEventArgs e)
      {
          if (e.TextComposition.CompositionText.Length == 0)
              ImeFlag = false;
      }
      

      我在当前 IME 处于活动状态时删除任何 TextChanged 事件,然后在 IME 文本完成后添加回事件:

      private bool _imeFlag = false;
      private bool ImeFlag
      {
          get => _imeFlag;
          set
          {
              if (_imeFlag == value)
                  return;
      
              if (value)        
                  myTextbox.TextChanged -= MyTextbox_TextChanged;        
              else        
                  myTextbox.TextChanged += MyTextbox_TextChanged;
              
              _imeFlag = value;
         }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-05-02
        • 2012-01-27
        相关资源
        最近更新 更多