简体   繁体   English

如何创建多行文本框,在每行之前显示撇号

[英]How to create multiline textbox which shows apostrophe before each line

I want a multiline textbox which shows apostrophes before and after each line. 我想要一个多行文本框,该文本框在每行之前和之后显示撇号。 So that the textbox looks like: 这样文本框看起来像:

" Hello this  "
" is a funny  "
" string test "

Or for example: 或者例如:

// This is
// a muliline
// comment.

Edit: These special characters must be readonly and if the user copies text from the textbox these characters should not be included. 编辑:这些特殊字符必须是只读的,如果从文本框中的用户复制文本这些字符应该被包括在内。

This is very easy using two textboxes laid directly over one another. 使用两个彼此直接放置的文本框,这非常容易。 The rear one is a normal textbox with extra padding and transparent text. 后面的是一个普通的文本框,带有额外的填充和透明文本。 The front one has your extra characters but has its borders hidden and is IsHitTestVisible=False and Focusable=False so it doesn't interact with the user. 前一个有您的多余字符,但边框已隐藏,并且IsHitTestVisible=FalseFocusable=False因此它不会与用户交互。 The user interacts exclusively with the rear textbox but the front textbox is the one that displays the text. 用户只与后文本框交互,而前文本框是显示文本的文本框。 A binding with a value converter keeps the front textbox displaying exactly what the rear textbox displays, plus the extra characters. 与值转换器的绑定使前文本框准确显示后文本框显示的内容,以及额外的字符。

This is how it would look: 它是这样的:

<ControlTemplate x:Key="TextBoxWithExtraCharacters" TargetType="{x:Type TextBox}">
  <ControlTemplate.Resources>
    <!-- Remove the border from the inner textboxes -->
    <ControlTemplate TargetType="{x:Type TextBox}">
      <Decorator x:Name="PART_Content" />
    </ControlTemplate>
  </ControlTemplate.Resources>

  <!-- Now add our own border -->
  <Border
    BorderThickness="{TemplateBinding BorderThickness}"
    BorderBrush="{TemplateBinding BorderBrush}"
    Background="{TemplateBinding Background}"
    SnapsToDevicePixels="true">

    <!-- Scrolling must happen at this level so both text boxes scroll simultaneously -->
    <ScrollViewer>
      <Grid>
        <!-- Rear textbox provides editing and user interaction but the text is transparent -->
        <TextBox
          Margin="10,0,10,0"
          Foreground="Transparent"
          Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}"
          Background="{x:Null}"
          IsReadOnly="{TemplateBinding IsReadOnly}"
          IsUndoEnabled="{TemplateBinding IsUndoEnabled}"
          AcceptsReturn="{TemplateBinding AcceptsReturn}"
          AcceptsTab="{TemplateBinding AcceptsTab}"
        />
        <!-- Front textbox displays modified text but does not interact with user -->
        <TextBox
          IsHitTestVisible="false"
          Focusable="false"
          Text="{Binding Text, RelativeSource={RelativeSource TemplatedParent}, 
                               Converter={x:Static ExtraCharacterConverter.Instance}"
          Background="{x:Null}"
          IsReadOnly="{TemplateBinding IsReadOnly}"
          IsUndoEnabled="{TemplateBinding IsUndoEnabled}"
          AcceptsReturn="{TemplateBinding AcceptsReturn}"
          AcceptsTab="{TemplateBinding AcceptsTab}"
        />
      </Grid>
    </ScrollViewer>
  </Border>
</ControlTemplate>

ExtraCharacterConverter is a simple IValueConverter class that implements the Convert method by taking the given string, appending quotes or // or whatever to it, and returning the result. ExtraCharacterConverter是一个简单的IValueConverter类,该类通过获取给定的字符串,在其后加上引号或//或其他内容并返回结果来实现Convert方法。

Note that I hard-coded a left and right margin of 10 units on the rear textbox, which assumes a particular width for the quote characters. 请注意,我在后文本框上硬编码了10个单位的左右边距,假定引号字符的宽度是特定的。 This should be exactly the width of the added characters to make the text line up correctly. 这应该恰好是所添加字符的宽度,以使文本正确对齐。 You want to get this right, or your caret and text selection positioning will be wrong. 您想得到正确的选择,否则插入符号和文本选择的位置将是错误的。 Also note that the correct value will change as you vary your font size and your choice of extra characters. 还要注意,随着字体大小和其他字符的选择,正确的值也会改变。

An easy alternative to hard-coding the margin would be to set it to a multi-binding on FontSize, FontFamily, FontWeight , etc, then use a IMultiValueConverter to compute the proper margin given this these values. 硬编码裕度的一个简单替代方法是将其设置为FontSize, FontFamily, FontWeight等的多重绑定,然后使用IMultiValueConverter来给定这些值来计算适当的裕度。

Note: This solution is slighly unsatisfactory when it comes to the color scheme for text selection. 注意:当涉及到用于文本选择的配色方案时,此解决方案绝对不能令人满意。 This can be fixed, but it requires a more complex solution: The rear text box is the same but its text is not invisible. 此问题可以解决,但需要更复杂的解决方案:后面的文本框相同,但其文本不可见。 The front text box is replaced with a RichTextBox (or TextBlock) whose content is computed dynamically to be the text with extra characters, but the regular text transparent. 前面的文本框替换为RichTextBox(或TextBlock),其内容被动态计算为带有额外字符的文本,但常规文本透明。 Because it is a RichTextBox the extra characters can be visible while the others are transparent. 因为它是RichTextBox,所以可以看到其他字符,而其他字符是透明的。

Can you not simply create a user defined textbox using inheritance with the multiline property set to true, and some special code on the text changed event to check the first and last index on each line to ensure it has an apostrophe there? 您是否不能简单地使用multiline属性设置为true的继承来创建用户定义的文本框,并在文本更改事件上使用一些特殊代码来检查每行的第一个和最后一个索引,以确保该行上有撇号? or if there is no way to iterate lines, can you just watch the character before and after every chr(11) or chr(13)? 或者,如果没有办法迭代行,您是否可以只在每个chr(11)或chr(13)之前和之后观看字符?

This wouldn't be difficult with winforms, i'm not sure about WPF however. 对于winforms,这并不困难,但是我不确定WPF。

~~~~~~~~~~~~~~~~~~~~~~~~~Edit 1: 11/25/2009 9:12 AM CT~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~编辑1:1/25/2009 9:12 AM CT ~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~

If you would like it so that the user cannot edit or mess with the quotes, then you could write specific code in the KeyPressed event handler (or override the OnKeyPressed function if you are doing an inherited control) to keep them from adding characters before or after a chr(11) or chr(13), and add it back immediately if they attempt to delete it, and cancel invalid keystrokes. 如果您希望用户不能对其进行编辑或使引号混乱,则可以在KeyPressed事件处理程序中编写特定的代码(如果正在执行继承的控件,则可以重写OnKeyPressed函数),以防止它们在之前或之后添加字符。在chr(11)或chr(13)之后,如果他们试图删除它并取消无效的击键,请立即将其重新添加。

I've written code similar to this in VB .NET for a money text box field. 我在VB .NET中为钱文本框字段编写了与此类似的代码。 It may help you to understand what i'm talking about, and it may assist you in what you are doing: 它可以帮助您了解我在说什么,也可以帮助您进行操作:

Protected Overrides Sub OnMouseClick(ByVal e As System.Windows.Forms.MouseEventArgs)
    If Me.SelectionStart = 0 Then
        Me.SelectionStart = Me.Text.Length
    End If
End Sub

Protected Overrides Sub OnTextChanged(ByVal e As System.EventArgs)
    If Not Me.Text.IndexOf("$") = 0 Then
        Me.Text = "$" + Me.Text.Replace("$", "")
    End If
    If Me.SelectionStart = 0 Then
        Me.SelectionStart = Me.Text.Length
    End If
End Sub

Protected Overrides Sub OnKeyPress(ByVal e As System.Windows.Forms.KeyPressEventArgs)
    If NOT ((Char.IsDigit(e.KeyChar) Or (e.KeyChar = CChar(".") And Not Me.Text.Contains(".")) Or Char.IsControl(e.KeyChar)) And (Not Char.IsDigit(e.KeyChar) Or (Me.SelectionStart <= Me.Text.IndexOf(".") + 2 Or Me.Text.IndexOf(".") = -1))) Then
        e.Handled = True
    End If
End Sub

我想说,最好的选择是实现自己的文本框(从文本框本身继承而来,因此您可以免费获得所有功能),并覆盖绘图代码并自己写出每一行(在输入之前/之后添加)在写出每一行时都用单引号引起来)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何将一行添加到多行文本框? - How to add a line to a multiline TextBox? 如何在TextBox Multiline中选择行号 - HOW TO SElect line number in TextBox Multiline 如何在多行文本框中的每个新行中添加数字C#/ ASP.net - How to add number in each new line in a multiline textbox C# / ASP.net 如何使用C#在PowerPoint TaskPane上限制多行文本框中每行的长度? - How to limit the length of each line in a multiline textbox on PowerPoint TaskPane using C#? 如何在多行TextBox中制作命令行 - how to make command line in a multiline TextBox 如何从多行文本框中为 C# 中的每一行创建 2 个 arrays? 然后我需要在图中 plot 那些 arrays - How create 2 arrays from a multiline textbox for each row in C#? Then I need to plot in a graph those arrays 如何使用C#在多行文本框中最后一行之后的新行上设置光标位置? - How can I set the cursor position at the new line which is after the last line in a multiline textbox using C#? c#如何逐行读取和写入多行文本框? - c# How to read and write from multiline textBox line by line? 限制多行文本框中的行长 - Limit line length in multiline textbox 如何在asp.net中的多行文本框中增加行距? - How to increase the line spacing in a multiline textbox in asp.net?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM