在 WPF 中使用 ItemsControl 时正确对齐控件

Align controls correctly when using ItemsControl in WPF

谁能告诉我在使用 ItemsControl 时如何正确对齐和调整控件大小。

我想在 ObservableCollection 中定义的多个字段的左侧有一个描述,右侧有一个 TextBox 以结束类似:

First Name:    [FirstNameTextBox]
Last Name:     [LastNameTextBox]
Date of Birth: [DobTextBox]

但我得到的是:

First Name: [FirstNameTextBox]
Last Name: [LastNameTextBox]
Date of Birth: [DobTextBox]

我希望所有文本框都基于最大的 <TextBlock> 对齐。如果这是直接在 <Grid> 控件中完成的,那将是直截了当的,因为所有控件都直接在网格中,您只需定义以下列定义

<Grid.ColumnDefinitions>
    <ColumnDefinition Width="Auto"/>
    <ColumnDefinition/>
</Grid.ColumnDefinitions>

我以为我可以在 <Grid> 中使用 SharedSizeGroup 属性,但它仍然无法正确调整大小。相反,它仅显示 <Grid>.

<TextBlock> 延伸

这是我的代码:

<Grid Grid.IsSharedSizeScope="True" Grid.Row="1">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" SharedSizeGroup="Labels" />
        <ColumnDefinition Width="*" SharedSizeGroup="InputControls" />
    </Grid.ColumnDefinitions>
    <ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedTemplate.Fields}">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="Labels"/>
                        <ColumnDefinition SharedSizeGroup="InputControls"/>
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Path=Label}" Grid.Column="0" Margin="5" 
                     VerticalAlignment="Center" Background="Red" />
                    <TextBox Text="{Binding Path=Value}"  Grid.Column="1" Margin="5" 
                     VerticalAlignment="Center" Background="Blue" />
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

知道如何解决这个问题吗?

谢谢。

UPDATE1: 我无法按需要让它工作。这是我到目前为止得到的:

<Grid Grid.Row="1" Background="Purple">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" SharedSizeGroup="Overall" />
    </Grid.ColumnDefinitions>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
            <ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
        </Grid.ColumnDefinitions>
        <ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"                               
                  Background="Yellow" 
                  Grid.IsSharedSizeScope="True">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid Background="Green">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="Labels"/>
                            <ColumnDefinition SharedSizeGroup="InputControls"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Path=Label}" 
                               Grid.Column="0" 
                               Margin="5"
                               VerticalAlignment="Center"/>
                        <TextBox Text="{Binding Path=Name}"  
                             Grid.Column="1" 
                             Margin="5"
                             VerticalAlignment="Center"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>

这最终以这种方式显示了我的布局:

如您所见,我的 TextBox 已根据最大的 TextBlock 正确对齐,但我的 ItemsControls 并未一直延伸。我想这是有道理的,因为它在定义 ColumnDefinitions 的同一网格内。

现在,如果我移动 ColumnDefinitions' out this grid to the outer grid and remove all instances ofGrid.IsSharedSizeScope`,我猜如下:

这又一次更接近我的需要,因为我的 ItemsControl 现在一直延伸,因为我已经设置了它的 Grid.ColumnSpan="2" 并且我的 TextBox 仍然与 [=26= 对齐] 并且一直在延伸,但现在的问题是 TextBlock 应该更小,因为 Column 设置为 Auto 但它们的行为似乎就像该列设置为 * 我想我正在失去使用 IsSharedSizeScope 的目的,因为它已被删除。

现在,如果我将 IsSharedSizeScope="True" 添加到外部网格,我会得到以下结果:

同样,这接近我想要的,因为我的 ItemsControl 被拉伸了,我的文本框也被拉伸了,但它们不再与最大的对齐 TextBlock

最后,如果我按照@mm8最初的建议将Grid.IsSharedSizeScope="True"添加到ItemsControl

<Grid Grid.Row="1" Background="Purple" Grid.IsSharedSizeScope="True">
    <Grid.ColumnDefinitions>
        <ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
        <ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
    </Grid.ColumnDefinitions>
    <Grid Grid.ColumnSpan="2" >
        <ItemsControl ItemsSource="{Binding SelectedTemplate.Fields}"                               
                      Background="Yellow" 
                      Grid.IsSharedSizeScope="True">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <Grid Background="Green">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition SharedSizeGroup="Labels"/>
                            <ColumnDefinition SharedSizeGroup="InputControls"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Text="{Binding Path=Label}" 
                               Grid.Column="0" 
                               Margin="5"
                               VerticalAlignment="Center"/>
                        <TextBox Text="{Binding Path=Name}"  
                             Grid.Column="1" 
                             Margin="5"
                             VerticalAlignment="Center"/>
                    </Grid>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>

    <!--<TextBlock Text="Invoice Number" Grid.Column="0" Margin="5" VerticalAlignment="Center"/>
        <TextBox Text="InvoiceNumber" Grid.Column="1" Margin="5" VerticalAlignment="Center"/>-->
</Grid>

我得到以下信息:

尽管定义不同,这让我回到了第一点?

我需要实现以下目标:

我做错了什么??

谢谢。

尝试设置 ItemsControl 本身的 Grid.IsSharedSizeScope 属性:

<ItemsControl Grid.Row="1" ItemsSource="{Binding SelectedBarcodeTemplate.Fields}" 
              Grid.IsSharedSizeScope="True">

同步 ItemsControl 中元素的宽度: https://joshsmithonwpf.wordpress.com/2008/09/06/synchronizing-the-width-of-elements-in-an-itemscontrol/

我最终在以下文章中找到了答案:WPF Tutorial - Grid Panel 部分:"How to share the width of a column over multiple grids"。

根据文章:

Columns and rows that participate in size-sharing do not respect Star sizing. In the size-sharing scenario, Star sizing is treated as Auto. Since TextWrapping on TextBlocks within an SharedSize column does not work you can exclude your last column from the shared size. This often helps to resolve the problem.

所以我的最终 XAML 看起来像这样:

<Grid Grid.Row="1" Background="Purple" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="Labels" Width="Auto" />
            <ColumnDefinition SharedSizeGroup="InputControls" Width="*" />
        </Grid.ColumnDefinitions>
    </Grid>

    <ItemsControl ItemsSource="{Binding SelectedBarcodeTemplate.Fields}"
                  Background="Yellow"
                  Grid.IsSharedSizeScope="True">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <Grid Background="Green" ShowGridLines="True">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition SharedSizeGroup="Labels"/>
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <TextBlock Text="{Binding Path=Label}" 
                               Grid.Column="0" 
                               Margin="5"
                               VerticalAlignment="Center"/>
                    <TextBox Text="{Binding Path=Name}"  
                             Grid.Column="1" 
                             Margin="5"
                             VerticalAlignment="Center"
                             HorizontalAlignment="Stretch"/>
                </Grid>
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>

结果现在看起来终于正确了:

希望这对其他人有帮助!