如何让WPF中不同自定义控件的Label与Value列尺寸统一?
WPF 跨自定义控件统一Label与Value列尺寸解决方案
当前自定义控件LabelTexUserControl的Label和Value列无法跨控件对齐,核心原因是每个UserControl内部的Grid单独设置了IsSharedSizeScope="True",导致SharedSizeGroup仅在当前控件内部生效,无法与其他控件共享尺寸。
解决方案
- 移除自定义控件内部Grid的
IsSharedSizeScope属性,让父容器的SharedSizeScope全局生效 - 确保所有控件的列使用相同的
SharedSizeGroup名称 - 保持父容器(MainWindow的Grid)的
IsSharedSizeScope="True"
修改后的LabelTexUserControl XAML
<UserControl x:Class="LabelDoubleTextBox.LabelTexUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:LabelDoubleTextBox" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <!-- 移除内部Grid的IsSharedSizeScope="True" --> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" SharedSizeGroup="LabelColumn"/> <ColumnDefinition Width="Auto" SharedSizeGroup="ValueColumn"/> </Grid.ColumnDefinitions> <Label Grid.Column="0" Content="{Binding Label,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LabelTexUserControl}}}" Margin="5"/> <Label Grid.Column="1" Content="{Binding Value,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:LabelTexUserControl}}}" Margin="5" /> </Grid> </UserControl>
LabelTexUserControl后台代码(无需修改)
public partial class LabelTexUserControl : UserControl { public LabelTexUserControl() { InitializeComponent(); } public static readonly DependencyProperty LabelProperty = DependencyProperty.Register( nameof(Label), typeof(string), typeof(LabelTexUserControl), new PropertyMetadata(default(string))); public string Label { get { return (string)GetValue(LabelProperty); } set { SetValue(LabelProperty, value); } } public static readonly DependencyProperty ValueProperty = DependencyProperty.Register( nameof(Value), typeof(string), typeof(LabelTexUserControl), new PropertyMetadata(default(string))); public string Value { get { return (string)GetValue(ValueProperty); } set { SetValue(ValueProperty, value); } } }
MainWindow XAML(无需修改,已正确配置)
<Window.DataContext> <local:MainWindowVM/> </Window.DataContext> <Grid IsSharedSizeScope="True"> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <local:LabelTexUserControl Grid.Row="0" Label="My Label" Value="{Binding VMValue}"/> <local:LabelTexUserControl Grid.Row="1" Label="Warning...... but I am just super loooong... lalala" Value="{Binding Terrify}"/> </Grid>
MainWindowVM代码(无需修改)
public class MainWindowVM { public string VMValue => "This is a value"; public string Terrify => "Dont be terrify"; }
原理说明
IsSharedSizeScope的作用范围是当前容器及其直接/间接子元素。之前在每个UserControl内部的Grid开启该属性,导致每个控件的SharedSizeGroup仅在自身内部生效。将IsSharedSizeScope移到父容器(MainWindow的Grid)后,所有子控件的SharedSizeGroup会在整个父容器范围内共享尺寸:Label列会自动调整为所有Label中的最大宽度,Value列同理,实现全局对齐效果。
内容的提问来源于stack exchange,提问作者Graviton
相关产品推荐
相关产品推荐

