WPF 中带有 TextBox 的 TreeViewItem:键入特殊字符

TreeViewItem with TextBox in WPF: type special characters

我需要编辑一些层次结构,我使用 TreeViewTextBoxes

简短示例

<TreeView>
    <TreeView.Items>
        <TreeViewItem Header="Level 0">
            <!-- Level 1-->
            <TextBox Margin="5"
                     BorderThickness="1" BorderBrush="Black" />
        </TreeViewItem>
    </TreeView.Items>
</TreeView>

当我输入 TextBox+- 时,字母和数字工作正常,箭头工作但当我按 -Level 0项目崩溃,当我键入 * 时,没有任何反应

我应该如何处理 -* 才能按预期在 TextBox 中看到它们?

编辑:

- 如果输入 Key.OemMinus 有效,但从数字键盘输入 Key.Subtract

无效

* 如果输入为 Shift+Key.D8 可以工作,但不能从数字键盘输入为 Key.Multiply

我可以为您的文本框建议一个按键事件。

<TextBox Margin="5" KeyDown="TextBox_KeyDown"
                     BorderThickness="1" BorderBrush="Black" />


 private void TextBox_KeyDown(object sender, KeyEventArgs e)
 {
    TextBox txt = sender as TextBox;
    if(e.Key == Key.Subtract)
    {
        txt.Text += "-";
        txt.SelectionStart = txt.Text.Length;
        txt.SelectionLength = 0;
        e.Handled = true;
    }
    else if (e.Key == Key.Multiply)
    {
        txt.Text += "*";
        txt.SelectionStart = txt.Text.Length;
        txt.SelectionLength = 0;
        e.Handled = true;
    }
}

这不是一个好的解决方案,但它确实有效。如果您有任何其他 "problem" 键,您可以向事件添加一个 if。

SelectionStartSelectionLength 用于将光标定位在文本框的末尾。 e.Handled = true; 确实阻止了默认行为。

终于解决了Key.Subtract

的问题

我在 TextBox

上向 PreviewKeyDown 添加了处理程序
<TextBox Margin="5" BorderThickness="1" BorderBrush="Black" 
         PreviewKeyDown="TextBoxPreviewKeyDown"
/>

收到 Key.Subtract 后,KeyDown 被标记为已处理,然后我手动引发 TextInput 事件,如本 answer (How can I programmatically generate keypress events in C#? )

中所述
private void TextBoxPreviewKeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Subtract)
    {
        e.Handled = true;

        var text = "-";
        var target = Keyboard.FocusedElement;
        var routedEvent = TextCompositionManager.TextInputEvent;

        target.RaiseEvent(
            new TextCompositionEventArgs
                (
                     InputManager.Current.PrimaryKeyboardDevice,
                    new TextComposition(InputManager.Current, target, text)
                )
                {
                    RoutedEvent = routedEvent
                });
    }
}