Wpf:Grid:如何共享列/行高/宽?

uidvcgyl  于 2023-04-13  发布在  其他
关注(0)|答案(4)|浏览(183)

我有一个3列5行的网格:

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

    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>

    <Label Grid.Row="0" Grid.Column="0">Gas Volume Fraction</Label>
    <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=GasVolumeFraction}" MinWidth="40"></TextBox>
    <Label Grid.Row="0" Grid.Column="2">-</Label>

    <Label Grid.Row="1" Grid.Column="0">Density</Label>
    <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Density}" MinWidth="40"></TextBox>
    <Label Grid.Row="1" Grid.Column="2">kg/m3</Label>

    <Label Grid.Row="2" Grid.Column="0" Content="Curve speed" Style="{StaticResource curveSpeed}" ></Label>
    <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=Density}" Style="{StaticResource curveSpeed}" MinWidth="40"></TextBox>
    <Label Grid.Row="2" Grid.Column="2" Style="{StaticResource curveSpeed}">rpm</Label>

    <WrapPanel Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3">
        <RadioButton>Delta pressure</RadioButton>
        <RadioButton>Head</RadioButton>
    </WrapPanel>

    <WrapPanel Grid.Row="4" Grid.Column="0" Grid.ColumnSpan="3">
        <RadioButton>Efficiency</RadioButton>
        <RadioButton>Power</RadioButton>
        <RadioButton>Torque</RadioButton>
    </WrapPanel>

</Grid>

文本框和单选按钮有不同的空间需求,这使得行根据其内容呈现不同的高度。我如何使行均匀大小,但不大于必要的大小?换句话说:我希望为包含文本框(网格中最大的元素)的行设置Height=“Auto”的高度,然后对所有行使用该高度。

at0kjp5o

at0kjp5o1#

实际上有一个非常简单的解决方案,使用SharedSizeScope提到的here

<Grid Grid.IsSharedSizeScope="True">
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" SharedSizeGroup="groupName" />
        <RowDefinition Height="Auto" SharedSizeGroup="groupName" />
        <RowDefinition Height="Auto" SharedSizeGroup="groupName" />
    </Grid.RowDefinitions>
    ...
</Grid>

只要确保将Grid.IsSharedSizeScope设置为true,并确保每个RowDefinition具有相同的SharedSizeGroup,行应该是自动的,大小相等。

dced5bon

dced5bon2#

理想情况下,您应该使用具有星星型大小的行,并将Grid设置为VerticalAlignment="Top",但不幸的是,当网格根据其内容调整大小时,星型大小不起作用。
与使用单个网格不同,垂直布局使用UniformGrid,水平布局使用嵌套的网格控件。您可以在内部网格中的列上设置SharedSizeScope,以便在它们之间共享列大小。

<UniformGrid Rows="5" VerticalAlignment="Top" Grid.IsSharedSizeScope="True">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition SharedSizeGroup="B"/>
            <ColumnDefinition SharedSizeGroup="C"/>
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0">Gas Volume Fraction</Label>
        <TextBox Grid.Column="1" Text="{Binding Path=GasVolumeFraction}" MinWidth="40"></TextBox>
        <Label Grid.Column="2">-</Label>
    </Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition SharedSizeGroup="B"/>
            <ColumnDefinition SharedSizeGroup="C"/>
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0">Density</Label>
        <TextBox Grid.Column="1" Text="{Binding Path=Density}" MinWidth="40"></TextBox>
        <Label Grid.Column="2">kg/m3</Label>
    </Grid>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A"/>
            <ColumnDefinition SharedSizeGroup="B"/>
            <ColumnDefinition SharedSizeGroup="C"/>
        </Grid.ColumnDefinitions>
        <Label Grid.Column="0" Content="Curve speed" Style="{StaticResource curveSpeed}"></Label>
        <TextBox Grid.Column="1" Text="{Binding Path=Density}" Style="{StaticResource curveSpeed}" MinWidth="40"></TextBox>
        <Label Grid.Column="2" Style="{StaticResource curveSpeed}">rpm</Label>
    </Grid>
    <WrapPanel>
        <RadioButton>Delta pressure</RadioButton>
        <RadioButton>Head</RadioButton>
    </WrapPanel>
    <WrapPanel>
        <RadioButton>Efficiency</RadioButton>
        <RadioButton>Power</RadioButton>
        <RadioButton>Torque</RadioButton>
    </WrapPanel>
</UniformGrid>
n8ghc7c1

n8ghc7c13#

您可以使用绑定到最大TextBlock的ActualWidth和ActualHeight。

<Grid x:Name="grid" ShowGridLines="True">
        <Grid.RowDefinitions>
            <RowDefinition Height="{Binding Path=ActualHeight, ElementName=biggestTB}"/>
            <RowDefinition Height="{Binding Path=ActualHeight, ElementName=biggestTB}"/>                        
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="{Binding Path=ActualWidth, ElementName=biggestTB}"/>
            <ColumnDefinition Width="{Binding Path=ActualWidth, ElementName=biggestTB}"/>                        
        </Grid.RowDefinitions>
        <TextBlock Grid.Row="0" Grid.Column="0" x:Name="biggestTB" Text="biggest textblock content" TextWrapping="Wrap"/>
        <TextBlock Grid.Row="1" Grid.Column="1" Text="content" TextWrapping="Wrap"/>
    </Grid>
jljoyd4f

jljoyd4f4#

我的问题与上面的问题类似,但略有不同,因为IsSharedSizeScope方法和使用ActualWidth的绑定方法都没有为我解决这个问题。所以,我发布了另一个解决方案,希望有人能发现这个有用。所以,这里是我需要解决的问题:
我有一个应用程序,其中我有一个带有拆分视图的控件-参见下面的蓝色部分-虽然我喜欢在显示器的中间有一个GridSplitter,但我想在一个单独的控件中实现蓝色部分,而在它上面的部分应该在一个单独的程序集中实现:x1c 0d1x...但是GridSplitter应该在用户不知道实际分离的情况下穿过主视图并连接两个区域。我通过在拖动TopSplitterMainSplitter时设置列宽来实现这一点。

此方法没有性能损失,适用于“*”大小的列。

事实证明,同步两个或多个GridSplitter(如本例所示)实际上需要我们同步由GridSplitter“调整大小”的列宽度。拖动Top-或MainSplitter,您会看到其他区域调整大小,就像这是一个分割器一样:-)

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="*"/>
    </Grid.RowDefinitions>

    <Grid Grid.Row="0" Margin="3,3,3,0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" Name="TopColumnA"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*" Name="TopColumnB"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="AntiqueWhite"
                   Margin="0,0,3,3"
                   />

        <GridSplitter
            Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" Name="TopSplitter"
            HorizontalAlignment="Stretch"
            Background="Gray" Width="6"
            DragCompleted="GridSplitter_DragCompleted"
            DragDelta="MainSplitter_DragDelta"
            />

        <TextBlock Grid.Column="2" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="AntiqueWhite"
                   Margin="3,0,0,3"
                   />
    </Grid>

    <Grid Grid.Row="1" Margin="3,0,3,3">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" Name="MainColumnA"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="*" Name="MainColumnB"/>
        </Grid.ColumnDefinitions>

        <TextBlock Grid.Column="0" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="Aqua"
                   Margin="0,0,3,0"
                   />

        <GridSplitter
            Grid.Column="1" Grid.Row="0" Grid.RowSpan="3" Name="MainSplitter"
            HorizontalAlignment="Stretch"
            Background="Black" Width="6"
            DragCompleted="GridSplitter_DragCompleted"
            DragDelta="MainSplitter_DragDelta"
            />

        <TextBlock Grid.Column="2" Grid.Row="0"
                   HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
                   Background="Aqua"
                   Margin="3,0,0,0"
                   />
    </Grid>
</Grid>

...下面是后面所需的代码:

private void GridSplitter_DragCompleted(object sender, DragCompletedEventArgs e)
{
    if (sender == MainSplitter)
    {
        TopColumnA.Width = MainColumnA.Width;
        TopColumnB.Width = MainColumnB.Width;
    }
    else
    {
        if (sender == TopSplitter)
        {
            MainColumnA.Width = TopColumnA.Width;
            MainColumnB.Width = TopColumnB.Width;
        }
    }
}

private void MainSplitter_DragDelta(object sender, DragDeltaEventArgs e)
{
    if (sender == MainSplitter)
    {
        TopColumnA.Width = MainColumnA.Width;
        TopColumnB.Width = MainColumnB.Width;
    }
    else
    {
        if (sender == TopSplitter)
        {
            MainColumnA.Width = TopColumnA.Width;
            MainColumnB.Width = TopColumnB.Width;
        }
    }
}

相关问题