WPF如何实现初始显示2行且限制内容不超2行的TextBox控件
问题1:初始状态TextBox仅占用1行高度的解决
WPF的MinLines属性在TextBox无内容时,默认高度计算仅会按照1行文本的高度渲染,不需要给Grid行设置固定高度,两种可行方案选其一即可:
- 方案1:直接给TextBox补充设置
VerticalContentAlignment="Top"以及初始填充两个空白换行:Text=" ",如果担心初始空白内容影响后续逻辑,可以在控件首次获取焦点时清空初始内容。 - 方案2(更推荐,无业务逻辑侵入):通过后台代码动态计算当前字体下2行文本的高度,赋值给TextBox的
MinHeight属性,适配不同字体大小场景,示例代码:
var formattedText = new FormattedText( "占位文本", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(Reasoning_TextBox.FontFamily, Reasoning_TextBox.FontStyle, Reasoning_TextBox.FontWeight, Reasoning_TextBox.FontStretch), Reasoning_TextBox.FontSize, Brushes.Black, VisualTreeHelper.GetDpi(Reasoning_TextBox).PixelsPerDip); Reasoning_TextBox.MinHeight = formattedText.Height * 2 + Reasoning_TextBox.Padding.Top + Reasoning_TextBox.Padding.Bottom + 2; // 最后加2是边框预留宽度
两种方案都可以让TextBox初始就撑开为2行高度,Grid行保持Height="Auto"即可。
问题2:MaxLines不限制输入行数的解决
WPF的MaxLines属性仅控制控件的显示高度,不会拦截超过行数的输入,你需要自行添加输入拦截逻辑,步骤如下:
- 给TextBox补充设置
VerticalScrollBarVisibility="Disabled",禁止超过2行后的滚动显示 - 监听TextBox的
TextChanged事件,判断行数超过2时撤销最近的输入,适配不同宽度字符的场景,示例代码:
private void Reasoning_TextBox_TextChanged(object sender, TextChangedEventArgs e) { var textBox = sender as TextBox; if (textBox == null) return; // 等待文本渲染完成后获取实际行数 textBox.Dispatcher.InvokeAsync(() => { if (textBox.LineCount > 2) { if (textBox.CanUndo) { textBox.Undo(); textBox.ClearUndo(); } } }, System.Windows.Threading.DispatcherPriority.Loaded); }
修改后的XAML代码参考
<Grid x:Name="EigenbelegGrid"> <Grid.ColumnDefinitions> <ColumnDefinition Width="auto"></ColumnDefinition> <ColumnDefinition></ColumnDefinition> <ColumnDefinition Width="auto"></ColumnDefinition> <ColumnDefinition Width="auto"></ColumnDefinition> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Height="auto"></RowDefinition> <RowDefinition Height="auto"></RowDefinition> </Grid.RowDefinitions> <!-- Preset --> <Label Content="Preset" Grid.Column="0" Grid.Row="0"></Label> <ComboBox x:Name="TemplateSelection_DropDown" Grid.Column="1" Grid.Row="0" IsEditable="True"/> <Button x:Name="SavePreset_Button" Content="Save" Grid.Column="2" Grid.Row="0"></Button> <Button x:Name="DeletePreset_Button" Content="Delete" Grid.Column="3" Grid.Row="0"></Button> <!-- Reasoning --> <Label Content="Begründung" Grid.Column="0" Grid.Row="1"></Label> <TextBox x:Name="Reasoning_TextBox" Grid.Column="1" Grid.Row="1" MinLines="2" MaxLines="2" TextWrapping="Wrap" MaxLength="200" VerticalScrollBarVisibility="Disabled" TextChanged="Reasoning_TextBox_TextChanged"> </TextBox> </Grid>
内容的提问来源于stack exchange,提问作者julian bechtold
相关产品推荐
相关产品推荐

