【问题标题】:In WPF, does PreviewTextInput always give a single character only?在 WPF 中,PreviewTextInput 是否总是只给出一个字符?
【发布时间】:2022-02-04 00:41:44
【问题描述】:

在 WPF 中处理 TextBox 的 PreviewTextInput 事件时,事件参数 (TextCompositionEventArgs) 的 Text 属性是否可以包含通过键盘输入的最后一个字符以外的内容?

我对其进行了彻底的测试,它似乎只包含最后按下的键的单个字符值。但是,我可能遗漏了一些明显的东西,因为它的类型是 String 而不是 Char

【问题讨论】:

    标签: c# wpf


    【解决方案1】:

    来自UIElement.PreviewTextInput 文档。

    键盘是PreviewTextInput的主要手段; 但讲话, 手写,其他输入设备也可以生成 预览文本输入

    我假设非键盘来源一次能够提供多个字母。

    【讨论】:

    • 我会补充的。从缓冲区插入/替换以及删除时,选择将立即更改字符范围。还有一些情况(没有想到例子),一个动作会改变一行中的多个范围。
    【解决方案2】:

    是的,它只会给你最后一个被按下的字符。

    【讨论】:

      【解决方案3】:

      是的,顾名思义,它会预览每个输入,大多数情况下恰好是单个字符。

      使用 TextCompositionEventArgs,您可以通过 e.Text 访问新文本。

      或者, 如果你想要全文,你可以得到它像

      string full = myTextBox.Text.Insert(myTextBox.CaretIndex, e.Text);
      

      【讨论】:

      • myTextBox = e.OriginalSource as TextBox
      【解决方案4】:

      它只会给你你按下的字符,你怎么能从文本框 Text 属性本身获取完整的文本,比如var text = (sender as TextBox).Text

      【讨论】:

      • 不幸的是,这似乎只返回事件之前的文本。
      • @Dragomok 如果要获取全文,可以获取TextBox,获取加法,添加到正确的位置:`String newText = (sender as TextBox).Text.Insert ((发件人为 TextBox).CaretIndex, e.Text)
      • @Gevo12321 这不会涵盖所有边缘情况,即替换现有文本。
      【解决方案5】:

      我发现这个问题需要通过 PreviewTextInput 检查 TextBox 中的结果文本。

      Gowshik 的回答和 Gevo12321 在 AMS 的回答中的评论的问题在于,它没有考虑到用户选择部分文本并用单个字符覆盖它(正如 hakamairi 所指出的)

      为了解决这个问题,我在插入新角色之前删除了选定的部分

      TextBox tB = (TextBox)sender;
      var oldText = tB.Text;
      oldText = oldText.Remove(tB.SelectionStart, tB.SelectionLength);
      string newText = oldText.Insert(tB.CaretIndex, e.Text);
      

      但是,下一个极端情况是人们选择部分文本并将其拖放到另一个位置。为此,我向PreviewDrop 事件添加了一个事件处理程序,并重建并检查结果字符串

      TextBox textBox = (TextBox)sender;
      
      // Get the index position of the dropped text
      Point position = e.GetPosition(textBox);
      int index = textBox.GetCharacterIndexFromPoint(position, true);
      
      // Remove the selected text, then insert it into the new position
      var oldText = textBox.Text;
      oldText = oldText.Remove(textBox.SelectionStart, textBox.SelectionLength);
      string newText = oldText.Insert(index, textBox.SelectedText);
      

      我能想到的最后一个边缘情况是人们粘贴到 TextBox 中,但在我的情况下,我禁用了该功能,因为它不需要。

      【讨论】:

        猜你喜欢
        • 2018-11-27
        • 1970-01-01
        • 2013-07-28
        • 2017-10-10
        • 2021-02-13
        • 2017-06-06
        • 2012-12-06
        • 2018-01-04
        • 1970-01-01
        相关资源
        最近更新 更多