【问题标题】:WPF Wrappanel nicely aligned Textblocks and TextboxesWPF Wrappanel 很好地对齐文本块和文本框
【发布时间】:2017-09-07 21:42:54
【问题描述】:

我已经敲了几个小时,试图弄清楚如何让我的文本块和文本框在 Wrappanel 中对齐。我已经尝试了可以​​在 stackoverflow 上找到的所有内容,但事实是在我的第一个 WPF 应用程序中,我很难弄清楚。

这篇文章详细描述了我想要实现的目标,但我无法使用此处概述的步骤使其工作:http://badecho.com/2012/07/wpf-grid-like-wrappanels/

这是我目前所拥有的:

<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>

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

有人可以给我一个愚蠢的解决方案吗?如果有一个简单的修复方法,我将不胜感激。

【问题讨论】:

    标签: c# wpf xaml wrappanel


    【解决方案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>
    

    这里的 Grid 是 Window 中的主要 Grid。可能需要一些技巧才能以您想要的方式获得它。

    【讨论】:

    • 艾德你是今天的王者!!!非常感谢,这正是我需要的!我很高兴您如此迅速,而且您的回答既简单又复杂。当我调整窗口大小时,我的文本框会折叠起来,但它们最终会落在我的数据网格后面。你能帮我一些建议,以便数据网格将在包装面板下移动吗?我需要添加什么?
    • @iCosmin 最简单的方法是去掉 DataGrid 上的巨大边距,并将 WrapPanel 和 DataGrid 堆叠在 &lt;StackPanel Orientation="Vertical"&gt;&lt;WrapPanel ... /&gt;&lt;DataGrid ... /&gt;&lt;/StackPanel&gt; 中——不要在 WPF 中使用边距进行布局,总有更好的选择。
    • 你也可以在 WrapPanel 周围放置一个 MaxHeight 的 ScrollViewer。
    • 将 ScrollViewer 添加到 WrapPanel 效果很好。但是,我按照您的步骤,取出了巨大的边距并将 dataGrid 放在 StackPanel 中。我现在的问题是我丢失了数据网格上的滚动条。当我最大化时,我只能看到水平的。有没有办法可以将两个滚动条都保留在 dataGrid 上?谢谢埃德!
    • 谢谢你,埃德。你真的帮了我大忙。祝你有美好的一天! :)
    猜你喜欢
    • 2023-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    • 2010-10-30
    • 2011-05-26
    • 2014-02-12
    相关资源
    最近更新 更多