C# WPF:如何在Menu中插入可自适应拉伸的TextBox?
WPF菜单嵌入TextBox的布局问题修复
我尝试在Menu中插入带灰色提示文本的TextBox,遇到两个问题:
- TextBox无法沿Menu整体拉伸;
- Menu出现异常偏移。
即使将其放入Grid后,右侧仍存在异常偏移,以下是最新实现代码:
<Window x:Class="NotepadMain.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:NotepadMain" mc:Ignorable="d" Title="FirePad - A Notepad for the 21st Century" Height="450" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <DockPanel LastChildFill="True" Grid.Row="0" VerticalAlignment="Center"> <Menu DockPanel.Dock="Top" FontFamily="Consolas" FontSize="20"> <MenuItem Header="_File" Width="auto"> <MenuItem Header="New" x:Name="newMenus" > <MenuItem.Icon> <Image Source="Assets/new.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Save" x:Name="saveMenus" Click="saveMenus_Click" > <MenuItem.Icon> <Image Source="Assets/save.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="SaveAs" x:Name="saveAsMenus" Click="saveAsMenus_Click" > <MenuItem.Icon> <Image Source="Assets/save_as.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Open" x:Name="openMenus" Click="openMenus_Click"> <MenuItem.Icon> <Image Source="Assets/open.png"/> </MenuItem.Icon> </MenuItem> <Separator /> <MenuItem Header="Print"> <MenuItem.Icon> <Image Source="Assets/print.png"/> </MenuItem.Icon> </MenuItem> </MenuItem> <MenuItem Header="Edit"> <MenuItem Header="Copy" x:Name="copyMenus" > <MenuItem.Icon> <Image Source="Assets/copy.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Paste" x:Name="pasteMenus" > <MenuItem.Icon> <Image Source="Assets/paste.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Cut" x:Name="cutMenus" > <MenuItem.Icon> <Image Source="Assets/cut.png"/> </MenuItem.Icon> </MenuItem> <Separator/> <MenuItem Header="Undo" x:Name="undoMenus" > <MenuItem.Icon> <Image Source="Assets/undo.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Redo" x:Name="redoMenus" > <MenuItem.Icon> <Image Source="Assets/redo.png"/> </MenuItem.Icon> </MenuItem> <Separator/> <TextBox TextWrapping="Wrap" Width="100" Grid.Column="0"> <TextBox.ToolTip>Highlight a Word in the Text</TextBox.ToolTip> </TextBox> </MenuItem> </Menu> </DockPanel> <RichTextBox Grid.Row="1" x:Name="richTextBox1"> </RichTextBox> </Grid> </Window>
修复方案
1. 解决TextBox拉伸问题
直接将TextBox作为MenuItem子元素会受MenuItem默认布局约束,需要将TextBox放在MenuItem的Header中,并用Grid或DockPanel包裹,让其填充MenuItem的可用宽度。同时添加灰色提示文本(水印效果),可以通过TextBox的Style实现。
2. 解决Menu偏移问题
移除DockPanel上的VerticalAlignment="Center",避免菜单垂直方向偏移;同时移除TextBox上无效的Grid.Column="0"属性(该属性仅在Grid容器内生效)。
修改后的完整代码
<Window x:Class="NotepadMain.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:NotepadMain" mc:Ignorable="d" Title="FirePad - A Notepad for the 21st Century" Height="450" Width="800"> <Window.Resources> <!-- 带灰色提示文本的TextBox样式 --> <Style TargetType="TextBox" x:Key="WatermarkTextBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TextBox"> <Grid> <TextBox x:Name="PART_ContentHost" Background="Transparent"/> <TextBlock x:Name="WatermarkText" Text="Highlight a Word in the Text" Foreground="Gray" IsHitTestVisible="False" Margin="5,0" Visibility="Collapsed"/> </Grid> <ControlTemplate.Triggers> <Trigger Property="Text" Value=""> <Setter TargetName="WatermarkText" Property="Visibility" Value="Visible"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> </Window.Resources> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <DockPanel LastChildFill="True" Grid.Row="0"> <Menu DockPanel.Dock="Top" FontFamily="Consolas" FontSize="20"> <MenuItem Header="_File"> <MenuItem Header="New" x:Name="newMenus" > <MenuItem.Icon> <Image Source="Assets/new.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Save" x:Name="saveMenus" Click="saveMenus_Click" > <MenuItem.Icon> <Image Source="Assets/save.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="SaveAs" x:Name="saveAsMenus" Click="saveAsMenus_Click" > <MenuItem.Icon> <Image Source="Assets/save_as.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Open" x:Name="openMenus" Click="openMenus_Click"> <MenuItem.Icon> <Image Source="Assets/open.png"/> </MenuItem.Icon> </MenuItem> <Separator /> <MenuItem Header="Print"> <MenuItem.Icon> <Image Source="Assets/print.png"/> </MenuItem.Icon> </MenuItem> </MenuItem> <MenuItem Header="Edit"> <MenuItem Header="Copy" x:Name="copyMenus" > <MenuItem.Icon> <Image Source="Assets/copy.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Paste" x:Name="pasteMenus" > <MenuItem.Icon> <Image Source="Assets/paste.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Cut" x:Name="cutMenus" > <MenuItem.Icon> <Image Source="Assets/cut.png"/> </MenuItem.Icon> </MenuItem> <Separator/> <MenuItem Header="Undo" x:Name="undoMenus" > <MenuItem.Icon> <Image Source="Assets/undo.png"/> </MenuItem.Icon> </MenuItem> <MenuItem Header="Redo" x:Name="redoMenus" > <MenuItem.Icon> <Image Source="Assets/redo.png"/> </MenuItem.Icon> </MenuItem> <Separator/> <!-- 用MenuItem包裹TextBox,设置Header为Grid让TextBox拉伸 --> <MenuItem> <MenuItem.Header> <Grid Margin="-4,0,-10,0"> <TextBox Style="{StaticResource WatermarkTextBox}" TextWrapping="Wrap" HorizontalAlignment="Stretch"/> </Grid> </MenuItem.Header> </MenuItem> </MenuItem> </Menu> </DockPanel> <RichTextBox Grid.Row="1" x:Name="richTextBox1"/> </Grid> </Window>
关键修改说明
- 新增
WatermarkTextBox样式,实现灰色提示文本(水印)效果:TextBox为空时显示提示文本,有内容时自动隐藏; - 将TextBox放在
MenuItem.Header内的Grid中,设置HorizontalAlignment="Stretch"让TextBox填充MenuItem的可用宽度; - 移除DockPanel的
VerticalAlignment="Center",消除菜单垂直偏移; - 给Grid添加
Margin="-4,0,-10,0",调整TextBox与MenuItem边缘的间距,消除默认布局带来的偏移。
内容的提问来源于stack exchange,提问作者user3348988
相关产品推荐
相关产品推荐

