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

时间:2015-02-06 15:40:14

标签: c# .net wpf silverlight

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

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

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

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

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

任何人都有任何想法如何检测在Silverlight平台中是否使用/活动IME?感谢。

2 个答案:

答案 0 :(得分:7)

我能够在WPF和Silverlight框架中解决这个问题。问题是由于在IME输入符号时处理TextBox文本,而Text正在使IME本身改变其输入,它看起来不像Windows操作系统正常处理并导致CLR异常。

我做的是:

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

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

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

答案 1 :(得分:0)

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