WinUI 3中如何通过Grid实现控件填满页面宽高?
解决WinUI聊天应用布局尺寸问题
核心修改点
1. 让Grid占满TabViewItem空间
TabViewItem的内容默认不会自动拉伸,需给内部Grid设置HorizontalAlignment="Stretch"和VerticalAlignment="Stretch",确保Grid能获取TabViewItem的全部可用空间,这样Grid的行高比例(12*、*)才会生效。
2. 让RichTextBlock无文本时也占满高度
- 移除ScrollViewer的
VerticalAlignment="Top",改为VerticalAlignment="Stretch",让ScrollViewer占满Grid第一行的全部高度。 - 给RichTextBlock设置
HorizontalAlignment="Stretch"和VerticalAlignment="Stretch",确保它在ScrollViewer内填满可用空间,即使无文本也会占满对应区域。
3. 让聊天输入框宽度展开
将包裹输入控件的StackPanel替换为Grid——StackPanel水平布局时无法让子控件自动填充剩余空间,而Grid可通过列定义实现:设置一列给按钮(宽度Auto),另一列用*让RichEditBox占满剩余宽度。
修改后的完整XAML代码
<DataTemplate x:Key="Template_Tab" x:DataType="local:Item"> <TabViewItem HeaderTemplate="{StaticResource Template_TabHeader}" IsClosable="True" CloseRequested="Close_Requested"> <!-- 设置Grid拉伸填满TabViewItem --> <Grid Margin="10,10,10,10" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <Grid.RowDefinitions> <RowDefinition Height="12*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> <RowDefinition Height="*"></RowDefinition> </Grid.RowDefinitions> <SplitView x:Name="splitView" Grid.Row="0" IsPaneOpen="{x:Bind IsOpenChannels}" OpenPaneLength="256" DisplayMode="Inline" PanePlacement="Right"> <SplitView.Pane> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <InfoBar Grid.Row="0" IsOpen="True" Severity="Informational" Title="" CloseButtonClick="Cmd_CloseList"/> <ListView Grid.Row="1" ItemsSource="{x:Bind Channels,Mode=OneWay}" x:Name="List_Channels" SelectionMode="Multiple" ItemTemplate="{StaticResource Template_Channel}" RightTapped="Channels_RightTap" DoubleTapped="Channels_DoubleTap"/> </Grid> </SplitView.Pane> <!-- 修改ScrollViewer的VerticalAlignment为Stretch --> <ScrollViewer Name="Scroll" Margin="0" VerticalAlignment="Stretch" VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Disabled"> <!-- 设置RichTextBlock拉伸填满ScrollViewer --> <RichTextBlock x:Name="Output" Margin="0,0,0,10" IsColorFontEnabled="True" IsTextScaleFactorEnabled="True" IsTextSelectionEnabled="True" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> </RichTextBlock> </ScrollViewer> </SplitView> <!-- 改用Stretch让Line填满宽度,移除绑定的ChatWidth --> <Line Stroke="SteelBlue" Grid.Row="1" x:Name="LineSep1" X1="0" Y1="0" X2="1" Y2="0" Margin="0,10,0,10" StrokeThickness="3" Stretch="Fill"/> <!-- 把StackPanel换成Grid实现输入框拉伸 --> <Grid x:Name="InputSP" Margin="0,10,10,0" Grid.Row="2" MaxHeight="70"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button x:Name="ib1" Grid.Column="0"> <FontIcon Glyph="" /> <Button.Flyout> <MenuFlyout> <MenuFlyoutItem Text="Reset"/> <MenuFlyoutSeparator/> <ToggleMenuFlyoutItem Text="Repeat" IsChecked="True"/> <ToggleMenuFlyoutItem Text="Shuffle" IsChecked="True"/> </MenuFlyout> </Button.Flyout> </Button> <!-- 设置RichEditBox拉伸填满剩余宽度 --> <RichEditBox x:Name="Input" Grid.Column="1" KeyDown="KD" AcceptsReturn="False" HorizontalAlignment="Stretch"/> </Grid> </Grid> </TabViewItem> </DataTemplate>
额外说明
WinUI采用自动流式布局,和Win32手动处理WM_SIZE调整控件的思路不同。核心是通过设置控件的HorizontalAlignment和VerticalAlignment为Stretch,配合Grid的行/列比例定义,让容器和子控件自动填充可用空间,无需手动计算尺寸。
内容的提问来源于stack exchange,提问作者Michael Chourdakis
相关产品推荐
相关产品推荐

