WPF Wrappanel很好地对齐了Textblocks和Textboxes

时间:2017-09-07 21:42:54

标签: c# wpf xaml wrappanel

我一直想敲打几个小时试图找出如何在Wrappanel中对齐我的文本块和文本框。我已经尝试了一些我可以在stackoverflow上找到的东西,但事实是在我的第一个WPF应用程序中,我很难搞清楚事情。

我想要实现的内容在本文中有详细介绍,但我无法使用此处列出的步骤使其工作:example

这是我到目前为止所拥有的:

<TabControl HorizontalAlignment="Left" 
    Margin="10,150,0,10"
    VerticalAlignment="Top">
<TabItem Header="Repairs">

<Grid Margin="0,0,10,0">

    <WrapPanel Grid.IsSharedSizeScope="True" Orientation="Horizontal" Margin="0,10,10,10">
        <TextBlock TextWrapping="WrapWithOverflow" Margin="20, 5, 0, 20">
         Regular Paid Hours
        </TextBlock>
        <TextBox Margin="20, 0, 10, 20" Width="45"></TextBox>

        <TextBlock TextWrapping="WrapWithOverflow" Margin="20, 5, 0, 20">
         Overtime Hours
        </TextBlock>
        <TextBox Margin="20, 0, 10, 20" Width="45"></TextBox>

        <TextBlock TextWrapping="WrapWithOverflow" Margin="20, 5, 0, 20">
         Repair Labor
        </TextBlock>
        <TextBox Margin="20, 0, 10, 20" Width="45"></TextBox>\

        <!-- There are a lot more -->  
    </WrapPanel>

    <DataGrid AutoGenerateColumns="False" ColumnHeaderStyle="{StaticResource lowCase}" Margin="20,180,10,70" Name="dtGrid" HorizontalAlignment="Left" CanUserResizeRows="False" ItemsSource="{Binding}" VerticalAlignment="Top" GridLinesVisibility="All">
        <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding Path=Location}" Header="Location"/>
            <DataGridTextColumn Binding="{Binding Path=Date, StringFormat ='MM-dd-yy'}" Header="Date"/>
            <DataGridTextColumn Binding="{Binding Path=RegularPaidHours}" Header="Regular Repair Hours"/>
        </DataGrid.Columns>
    </DataGrid>
</Grid>

我想要实现的目标:在调整窗口大小时应该对齐文本框,并且数据网格应该向下移动以适合所有文本块和文本框。我错过了什么?

有人能为我提供一个防眩目的解决方案吗?我很感激能够轻松解决问题。

1 个答案:

答案 0 :(得分:1)

这是一种使用隐式样式和HeaderedContentControls的方法。您可以在ControlTemplate中设置边距,宽度等。我把它留下了很多骨头。默认情况下,“InputCol”单元格将水平拉伸其内容,但您可以在示例中看到如何为特定控件取消该内容。容器上的“SharedSizeGroup”和“IsSharedSizeScope”是使所有标签宽度相同但不比它们需要的更宽的魔力。

<Window.Resources>
    <Style TargetType="WrapPanel" x:Key="WrapForm">
        <Setter Property="Orientation" Value="Horizontal" />
        <Setter Property="Grid.IsSharedSizeScope" Value="True" />
        <Style.Resources>
            <!-- Implicit style for all HeaderedContentControls -->
            <Style TargetType="HeaderedContentControl">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="HeaderedContentControl">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="Auto" SharedSizeGroup="LabelCol" />
                                    <ColumnDefinition Width="120" SharedSizeGroup="InputCol" />
                                </Grid.ColumnDefinitions>
                                <Label
                                    VerticalContentAlignment="Top"
                                    Grid.Column="0"
                                    Content="{TemplateBinding Header}" 
                                    />
                                <ContentControl
                                    VerticalContentAlignment="Top"
                                    Grid.Column="1"
                                    Content="{TemplateBinding Content}"
                                    />
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Style.Resources>
    </Style>
</Window.Resources>
<Grid>
    <WrapPanel Style="{StaticResource WrapForm}">
        <HeaderedContentControl Header="Regular Paid Hours">
            <TextBox />
        </HeaderedContentControl>
        <HeaderedContentControl Header="Overtime Hours">
            <TextBox />
        </HeaderedContentControl>
        <HeaderedContentControl Header="Repair Labor">
            <ComboBox HorizontalAlignment="Left" />
        </HeaderedContentControl>
        <HeaderedContentControl Header="This One Has Two">
            <StackPanel Orientation="Vertical">
                <CheckBox>One Thing</CheckBox>
                <CheckBox>Or Another</CheckBox>
            </StackPanel>
        </HeaderedContentControl>
    </WrapPanel>
</Grid>

更新

简单的双行网格布局:

<Grid>
    <Grid.RowDefinitions>
        <!-- 
        This 2* + 1* means "divide the grid vertically into three equal parts,
        and give two of them to row zero and one of them to row one". 
        You could give them both Height="*" and it'll be divided evenly, or 
        make one of them Height="Auto" and it'll get the height it takes up, 
        while the other one will get all the remainder. 
        -->
        <RowDefinition Height="2*" />
        <RowDefinition Height="1*" />
    </Grid.RowDefinitions>
    <ScrollViewer
        Grid.Row="0"
        >
        <WrapPanel 
            Style="{StaticResource WrapForm}"
            >
            <HeaderedContentControl Header="Regular Paid Hours">
                <TextBox />
            </HeaderedContentControl>
            <HeaderedContentControl Header="Overtime Hours">
                <TextBox />
            </HeaderedContentControl>
            <HeaderedContentControl Header="Repair Labor">
                <ComboBox HorizontalAlignment="Left" />
            </HeaderedContentControl>
            <HeaderedContentControl Header="This One Has Two">
                <StackPanel Orientation="Vertical">
                    <CheckBox>One Thing</CheckBox>
                    <CheckBox>Or Another</CheckBox>
                </StackPanel>
            </HeaderedContentControl>
        </WrapPanel>
    </ScrollViewer>
    <DataGrid
        Grid.Row="0">
        <!-- stuff -->
    </DataGrid>
</Grid>

此处的网格是窗口中的主网格。可能需要花一些时间才能按照您想要的方式获得它。