【问题标题】:Stop user from typing before generated text阻止用户在生成文本之前输入
【发布时间】:2015-06-19 00:33:53
【问题描述】:

我正在用 WPF(使用 C#)编写一个文本编辑器,它使用 RichTextBox 模拟聊天程序。当用户按下回车键时,相关的用户名会自动插入下一行。但是,如果用户键入的速度足够快,在输入和其他按键之间交替,他们的文本可以出现在生成的用户名之前。这是一个可以更好地证明这一点的屏幕截图:http://oi62.tinypic.com/fusv1j.jpg

以前的问题更严重,四处搜索后我尝试在插入后手动将插入符号位置设置到末尾;不幸的是,如果你走得足够快,仍然可以在首字母之前输入文本。

这是我的 RichTextBox 的 KeyUp 事件的 C#,以及相关的辅助方法:

private void textBoxEnterPressed(object sender, KeyEventArgs e)
{
    if (e.Key != Key.Enter || initialsCheckBox.IsChecked == false)
        return;

    Chumhandle active = getActiveHandleBox().SelectedItem as Chumhandle;
    AppendText(mainTextBox, active.Initials + ": ", active.HexCode);

    TextPointer caretPos = mainTextBox.CaretPosition;
    caretPos = caretPos.DocumentEnd;
    mainTextBox.CaretPosition = caretPos;
}

private ComboBox getActiveHandleBox()
{
    if (activeBox == 1)
        return handleBox1;
    else
        return handleBox2;
}

public static void AppendText(RichTextBox box, string text, string color)
{
    BrushConverter bc = new BrushConverter();
    TextRange tr = new TextRange(box.Document.ContentEnd, box.Document.ContentEnd);
    tr.Text = text;
    try
    {
        tr.ApplyPropertyValue(TextElement.ForegroundProperty, bc.ConvertFromString(color));
    }
    catch (FormatException) { }

    box.Selection.ApplyPropertyValue(RichTextBox.ForegroundProperty, bc.ConvertFromString(color));
}

以及 RichTextBox 的 XAML:

<RichTextBox Name="mainTextBox" Grid.Row="3" FontFamily="Courier New" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" BorderThickness="0" KeyUp="textBoxEnterPressed">
    <RichTextBox.Resources>
        <Style TargetType="{x:Type Paragraph}">
            <Setter Property="Margin" Value="0" />
        </Style>
    </RichTextBox.Resources>
</RichTextBox>

诚然,我不确定这是否可以解决,我只希望用户不要那么快......

【问题讨论】:

  • 你的盒子有一个比赛。两者都想处理回车键:你在textBoxEnterPressedRichTextBox 中添加一个新行。我会停止这个比赛设置AcceptsReturnFalse。它不应该在此处更改任何内容(除非您的对话框中有默认按钮),但我还将e.Handled 设置为true
  • 天哪,线程问题。哈哈。好吧,几乎做到了。比赛肯定是固定的(我只需要让textBoxEnterPressed 也手动插入一个新行)但是现在如果我将光标放在文本中间并按回车,所有内容都会附加到最后,而不是在光标位置很直观。让我想知道我是否错过了RichTextBox 自动处理的其他一些功能。
  • 没有线程,它是按顺序完成的。您甚至可以保持原样并将 e.Handled 设置为 true(如果您这样做,richtextbox 将无法处理输入)。实际上,只有当您在最后一行时,我才会检查是否做某事。下一步?两个框...一个用于查看对话,一个用于输入文本(几乎每个聊天都这样做...如果其他人在您仍在键入时打印消息怎么办?)
  • 我同意使用单独的文本框进行输入和聊天记录是个好主意。如果这是您想要的设计,您可以将它们设置为相同的控件,但是尝试使用单个文本框实例会导致很多问题,否则您将永远不必处理.
  • 嗯,问题是,这不是一个真正的聊天程序。没有在线功能。它只是一个文本编辑器,模拟一个特定的虚构聊天程序,自动格式化文档,使其看起来像来自它的日志。我还想让用户插入带有回车键的文本没有这种自动格式(这就是对initialsCheckBox的检查所做的)。我尝试将mainTextBox.AcceptsReturn 设置回true,同时保持e.Handled = true;,但这并不能解决问题。

标签: c# wpf richtextbox user-input


【解决方案1】:

Adriano Repetti 在 cmets 中获得了它;我不得不关闭文本框的 AcceptsReturn 并自己处理在输入时插入新行。

你和你的盒子比赛。两者都想处理 Enter 键:你在 textBoxEnterPressed 和 RichTextBox 中添加一个新行。我会停止这个比赛设置 AcceptsReturn 为 False。它不应该在此处更改任何内容(除非您的对话框中有默认按钮),但我还将 e.Handled 设置为 true。

【讨论】:

    【解决方案2】:

    我对您的代码进行了一些尝试,这就是我所管理的:

        private void textBoxEnterPressed(object sender, KeyEventArgs e)
        {
            if (e.Key != Key.Enter)
                return;
    
            // ADDED THIS TO SIMULATE AcceptsReturn = True
            if (initialsCheckBox.IsChecked == false)
            {
                AppendText(mainTextBox, Environment.NewLine, "#000000");
                return;
            }
    
            Chumhandle active = getActiveHandleBox().SelectedItem as Chumhandle;
    
            // ADDED Environment.NewLine TO INSERT LINE BREAKS
            AppendText(mainTextBox, Environment.NewLine + active.Initials + ": ", active.HexCode);
    
            // COMMENTED THIS BECAUSE IT WAS FORCING UNWANTED BEHAVIOR
            //TextPointer caretPos = mainTextBox.CaretPosition;
            //caretPos = caretPos.DocumentEnd;
            //mainTextBox.CaretPosition = caretPos;
        }
    
        public static void AppendText(RichTextBox box, string text, string color)
        {
            BrushConverter bc = new BrushConverter();
    
            // INSTEAD OF USING box.Document, I'VE USED box.Selection TO INSERT
            // THE TEXT WHEREVER THE CURSOR IS (OR IF YOU HAVE TEXT SELECTED)
            TextRange tr = new TextRange(box.Selection.Start, box.Selection.End);
            tr.Text = text;
            try
            {
                tr.ApplyPropertyValue(TextElement.ForegroundProperty, bc.ConvertFromString(color));
            }
            catch (FormatException) { }
    
            // I DON'T UNDERSTAND WHAT THIS IS DOING SO I KEPT IT -_^
            box.Selection.ApplyPropertyValue(RichTextBox.ForegroundProperty, bc.ConvertFromString(color));
    
            // FINALLY, I SET THE CARET TO THE END OF THE INSERTED TEXT
            box.CaretPosition = tr.End;
        }
    

    【讨论】:

    • 天哪,一旦我将 mainTextBox.AcceptsReturn 切换为 false 并改用它,这两个问题都 100% 解决了!太感谢了! :D
    • 很高兴我能帮上忙 :) 是的,我忘了提到 AcceptsReturn 的事情,呵呵(感谢 @AdrianoRepetti)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多