检测 IME(输入法编辑器)是否在 Silverlight 中处于活动状态

Detecting if IME (Input Method Editor) is active in Silverlight

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

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

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

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

有人知道如何检测 Silverlight 平台中的 IME 是否 used/active 吗?谢谢

我能够解决 WPF 和 Silverlight 框架中的问题。问题是由于在 IME 输入符号时处理 TextBox 文本导致文本使 IME 本身更改其输入,Windows OS 和导致 CLR 异常。

我所做的是:

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

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

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

希望对您有所帮助。

当某些 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;
   }
}