WPF提供了三个用于输入文本的控件:TextBox、RichTextBox和PasswordBox。PasswordBox控件直接继承自Control类。TextBox和RichTextBox控件间接继承自TextBoxBase类。
与前面看到的内容控件不同,文本框能够包含的内容类型是有限的。TextBox控件总是存储字符串(由Text属性提供)。PasswordBox控件也处理字符内容(由Password属性提供),尽管为了减轻特定类型的攻击,它在内部使用SecureString属性。只有RichTextBox控件可存储更复杂的内容:可包含复杂元素组合的FlowDocument对象。
一、多行文本
TextBox控件通常存储单行文本(可通过设置MaxLength属性来限制字符的数量)。然而,在许多情况下需要处理大量内容,从而会希望创建多行文本框。对于这种情况,可将TextWrapping属性设置为Wrap或WrapWithOverflow。如果将TextWrapping属性设置为Wrap,那么总是会在控件的边缘换行,设置将一个特别长的单词放在两行中。如果将TextWrapping属性设置为WrapWithOverflow,这时如果换行算法没有发现合适的位置(如空格或连字符)进行转换行,就允许拉伸某些行使其超出右边缘。
为了能自动在文本框中看到多行文本,需将其尺寸设置的足够大。不应该当设置硬编码的高度(这样不能适应不同的字体大小,而且可能导致布局问题),可使用方便的MinLines和MaxLines属性。MinLines属性是在文本框中必须显示的最小行数。例如,如果MinLines属性值为2,文本框的高度就会增大到至少两行的高度。如果容器的空间不足,部分文本框可能会被裁减掉。MaxLines属性设置文本框能够显示的最大行数。即使扩展文本框使其适合容器(例如,按比例改变尺寸的Grid控件的行或DockPanel中的最后一个元素),也不会超过这一限制。
如果文本框支持换行,用户可输入更多能够立即在可视行中显示的文本。因此,通过将VerticalScrollBarVisibility属性设置为Visible或Auto,添加始终显示或按需显示的滚动条是有意义的(也可设置HorizontalScrollBarVisibility属性来显示不常见的水平滚动条)。
可能希望允许用户在多行文本框中通过按下Enter键输入硬回车(通常,在文本框中按下Enter键将触发默认按钮)。为确保文本框支持Enter键,需要将AcceptsReturn属性设置为true。也可设置AcceptsTabs属性,从而允许用户插入Tab键。否则,Tab键会根据Tab键焦点顺序将焦点移到下一个可得到焦点的控件上。
有时,可能会创建纯粹为了显示文本的文本框。这是,可将IsReadOnly属性设置为true以阻止编辑文本。最好通过将IsEnabled属性设置为false来禁用文本框,因为禁用的文本框会显示变灰的文本,不支持文本选择(也不支持复制到剪切板),并且不支持滚动。
二、选择文本
在任何文本框中都可以通过单击并拖动鼠标,或按住Shift键并使用方向键在文本中移动来选择文本。TextBox类还提供了使用SelectionStart、SelectionLength以及SelectedText属性,通过编程决定选择哪些文本或改变当前所选文本的能力。
SelectionStart属性确定所选文本的开始位置,该位置是从0开始的。例如,如果将该属性设置为10,选择的第一个字符使文本框中的第11个字符。SelectionLength属性指示选中的字符的总数量(0表示没有选中字符)。最后,使用SelectedText属性可快速检查或改变在文本框中选中的文本。可通过处理SelectionChanged事件对文本选择变化加以响应。
<Window x:Class="Controls.TextBoxTest" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="TextBoxTest" Height="300" Width="300"> <Grid Margin="5"> <Grid.RowDefinitions> <RowDefinition Height="2*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <TextBox Name="txt" VerticalScrollBarVisibility="Auto" TextWrapping="Wrap" AcceptsReturn="True" SelectionChanged="txt_SelectionChanged" SpellCheck.IsEnabled="True">The Ministry of Truth contained, it was said, three thousand rooms above ground level, and corresponding ramifications below. Scattered about London there were just three other buildings of similar appearance and size. So completely did they dwarf the surrounding architecture that from the roof of Victory Mansions you could see all four of them simultaneously. They were the homes of the four Ministries between which the entire apparatus of government was divided. The Ministry of Truth, which concerned itself with news, entertainment, education, and the fine arts. The Ministry of Peace, which concerned itself with war. The Ministry of Love, which maintained law and order. And the Ministry of Plenty, which was responsible for economic affairs. Their names, in Newspeak: Minitrue, Minipax, Miniluv, and Miniplenty.</TextBox> <ScrollViewer Foreground="Blue" Grid.Row="1" Margin="0,10,0,5" VerticalScrollBarVisibility="Auto"> <StackPanel> <TextBlock>Current selection:</TextBlock> <TextBlock Name="txtSelection" TextWrapping="Wrap"></TextBlock> </StackPanel> </ScrollViewer> </Grid> </Window>