简体   繁体   English

在 WPF 中,有没有办法让 StackPanel 像网格一样具有对齐的列?

[英]In WPF, is there a way to make a StackPanel with aligned columns like a Grid?

For example I could do something like this:例如,我可以做这样的事情:

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition Width="Auto" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Width="Auto">
        <RowDefinition Width="Auto">
        <RowDefinition Width="Auto">
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="0" Grid.Column="0">Header 1</TextBlock>
    <TextBox Grid.Row="0" Grid.Column="1" MaxLines="1" />
    <Button Grid.Row="0" Grid.Column="2">Send</Button>
    <Button Grid.Row="0" Grid.Column="3">Save</Button>
    <TextBlock Grid.Row="1" Grid.Column="0">Header 2</TextBlock>
    <TextBox Grid.Row="1" Grid.Column="1" MaxLines="1" />
    <Button Grid.Row="1" Grid.Column="2">Send</Button>
    <Button Grid.Row="1" Grid.Column="3">Save</Button>
    <TextBlock Grid.Row="2" Grid.Column="0">Header 3</TextBlock>
    <TextBox Grid.Row="2" Grid.Column="1" MaxLines="1" />
    <Button Grid.Row="2" Grid.Column="2">Send</Button>
    <Button Grid.Row="2" Grid.Column="3">Save</Button>
</Grid>

Or I could do something like this:或者我可以做这样的事情:

<StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock>Header 1</TextBlock>
        <TextBox MaxLines="1" />
        <Button>Send</Button>
        <Button>Save</Button>
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock>Header 2</TextBlock>
        <TextBox MaxLines="1" />
        <Button>Send</Button>
        <Button>Save</Button>
    </StackPanel>
    <StackPanel Orientation="Horizontal">
        <TextBlock>Header 3</TextBlock>
        <TextBox MaxLines="1" />
        <Button>Send</Button>
        <Button>Save</Button>
    </StackPanel>
<StackPanel>

Except that I want to be able to easily manipulate the rows (add new rows, move rows around, etc.) just like in the StackPanel, while keeping the columns aligned properly just like in the Grid.除了我希望能够像在 StackPanel 中一样轻松地操作行(添加新行、移动行等),同时像在 Grid 中一样保持列正确对齐。

Here's a class I just threw together for approximately the same purpose - essentially I wanted to be able to put a bunch of labels in the left column and values of different types (text box, dropdown, etc) on the right.这是我为了大致相同的目的而拼凑在一起的一个类 - 基本上我希望能够在左列中放置一堆标签,并在右侧放置不同类型(文本框、下拉列表等)的值。

It only has two columns, but it could be adapted to different numbers.它只有两列,但可以适应不同的数字。

public class LabelValueGrid : Grid
{
    public LabelValueGrid()
        : base()
    {
        ColumnDefinitions.Add(new ColumnDefinition());
        ColumnDefinitions.Add(new ColumnDefinition());
        ColumnDefinitions[0].Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Auto);
        ColumnDefinitions[1].Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star);
    }

    protected override void OnVisualChildrenChanged(System.Windows.DependencyObject visualAdded, System.Windows.DependencyObject visualRemoved)
    {
        base.OnVisualChildrenChanged(visualAdded, visualRemoved);

        int curRow = -1;
        int curCol = 1;

        RowDefinitions.Clear();

        if (Children != null)
            foreach (System.Windows.UIElement curChild in Children)
            {
                if (curCol == 0)
                    curCol = 1;
                else
                {
                    curCol = 0;
                    curRow++;
                    RowDefinitions.Add(new RowDefinition() {Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Auto)});
                }

                Grid.SetRow(curChild, curRow);
                Grid.SetColumn(curChild, curCol);
            }

        RowDefinitions.Add(new RowDefinition() {Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star)});
    }
}

I can use this like a grid, except I just list the controls and then it alternates the columns automatically:我可以像网格一样使用它,除了我只列出控件然后它会自动交替列:

<local:LabelValueGrid>
    <TextBlock Text="Label1"/>
    <TextBox Name="value1"/>
    <TextBlock Text="Label2"/>
    <TextBox Name="value2"/>
</local:LabelValueGrid>

You could use many one-row Grids with size sharing on the columns.您可以在列上使用许多具有大小共享的Grids It gets verbose when done without any controls, so you could encapsulate some logic (like creating columns and assigning Grid.Column ) in a derivative of ItemsControl or an attached property for example.在没有任何控件的情况下完成时它会变得冗长,因此您可以将一些逻辑(例如创建列和分配Grid.Column )封装在ItemsControl的派生类或附加属性中。

Here's some reproducible code for a vertical StackPanel with an aligned column using SharedSizeGroups as alluded to by other answers.这是使用 SharedSizeGroups 的具有对齐列的垂直 StackPanel 的一些可重现代码,如其他答案所述。 It doesn't require any code-behind but you could add it if you wanted the panels to be created dynamically:它不需要任何代码隐藏,但如果您希望动态创建面板,则可以添加它:

<Grid Grid.IsSharedSizeScope="True">

<StackPanel Orientation="Vertical" VerticalAlignment="Stretch" Grid.ColumnSpan="1">

    <!-- ROW 0 -->

    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition SharedSizeGroup="FirstRow"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="FirstColumn" />
            <ColumnDefinition SharedSizeGroup="SecondColumn" />
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0">
            0-0 With extra width 
        </TextBlock>
        <TextBox Grid.Column="1">
            0,1
        </TextBox>
    </Grid>

    <!-- ROW 1 -->

    <Grid ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition SharedSizeGroup="FirstRow"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="FirstColumn"  />
            <ColumnDefinition SharedSizeGroup="SecondColumn"  />
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" HorizontalAlignment="Left">
            1-0
        </TextBlock>
        <TextBox Grid.Column="1">
            1,1 With extra width
        </TextBox>
    </Grid>

</StackPanel>

Notice the SharedSizeGroup labels for each column and the very top grid enabling such logic with Grid.IsSharedSizeScope="True" .请注意每列的SharedSizeGroup标签以及使用Grid.IsSharedSizeScope="True"启用此类逻辑的最顶部网格。 Creating the following image:创建以下图像:

在此处输入图片说明

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM