8

我有以下 XAML:

<Window x:Class="MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <TextBlock Text="0,0" Grid.Column="0" Background="Yellow" />
        <TextBlock Text="1,0" Grid.Column="1" Background="SkyBlue" />
        <GridSplitter Width="20" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Stretch" ShowsPreview="True" />
        <TextBlock Text="3,0" Grid.Column="3" Grid.Row="0" />
    </Grid>
</Window>

当只有一个ColumnDefinition带有WidthofAuto时,GridSplitter工作正常。但是,一旦有多个带有 aWidth的列Auto,第一Auto列也会在GridSplitter移动时调整大小(可以在 cell 中看到1,0)。

调整大小之前:

在此处输入图像描述

调整大小后:

在此处输入图像描述

如何防止 GridSplitter 调整第二列的大小?

4

3 回答 3

6

如果您无法修改现有列,也许您可​​以尝试以编程方式实现此行为...

为列命名:

<Grid.ColumnDefinitions>
    <ColumnDefinition Name="firstColumn" Width="*" />
    <ColumnDefinition Name="secondColumn" Width="Auto" />
    <ColumnDefinition Width="Auto" />
    <ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

将事件添加到网格分割器:

<GridSplitter Name="gridSplitter" DragStarted="gridSplitter_DragStarted" DragCompleted="gridSplitter_DragCompleted" />

然后在拆分器拖动之前保存列宽并将更改应用于第一列宽度,而不是第二个:

public partial class MainWindow : Window
{
    private double savedFirstColumnWidth;
    private double savedSecondColumnWidth;

    private void gridSplitter_DragStarted(object sender, DragStartedEventArgs e)
    {
        // Save the initial column width values
        savedFirstColumnWidth = firstColumn.ActualWidth;
        savedSecondColumnWidth = secondColumn.ActualWidth;
    }

    private void gridSplitter_DragCompleted(object sender, DragCompletedEventArgs e)
    {           
        double dragChange = e.HorizontalChange;

        // Change the width of the first column instead of second
        firstColumn.Width = new GridLength(savedFirstColumnWidth + dragChange);
        // Set the with of the second column to the value saved before the drag
        secondColumn.Width = new GridLength(savedSecondColumnWidth);
    }
}
于 2017-03-09T11:52:09.550 回答
2

我会修改布局以确保 GridSplitter 正在使用相邻的网格列:

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

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

        <TextBlock Text="0,0" Grid.Column="0" Background="Yellow" />
        <TextBlock Text="1,0" Name="Txt" Grid.Column="1" Background="SkyBlue" />
    </Grid>

    <GridSplitter Width="20" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Stretch" ShowsPreview="True" />
    <TextBlock Text="3,0" Grid.Column="2" Grid.Row="0" />
</Grid>
于 2017-03-06T13:13:16.437 回答
1

我一直在做一些测试,我相信我可以解释发生了什么,即使我不完全确定如何解决它。

测试:移动拆分器并观察 (0,0) 和 (3,0) 的相对大小。它们总是完全相等的。

结论:这种行为是因为 (0,0) 和 (3,0) 都是 * 宽度,因此它们中的每一个都有可用宽度的一半。但是,拆分器对 (3,0) 的大小进行了限制。由于 (3,0) 对其大小有限制,但也应该具有可用宽度的一半,这意味着 (0,0) 也具有与 (3,0) 相同的大小限制。由于拆分器迫使 (3,0) 收缩,因此 (0,0) 也必须收缩以保持 * 宽度指定的比例。因此 (1,0) 和 (2,0) 是唯一允许增长以填充剩余空间的列,并且由于 (2,0) 仅包含静态宽度为 20 的拆分器,因此 (1, 0) 增长以填充剩余空间。

正如我所说,我不确定如何解决这个问题,但解决问题的第一步是理解它。因此,希望这将有助于某人发现解决方案。

编辑:进一步测试表明,仅当 (1,0) 设置为自动或固定宽度时,上述情况才成立。如果 (1,0) 设置为 * 或 * 的某个倍数,则所有 * 部分的行为似乎都很奇怪,并且会在不考虑它们假定的比例的情况下增长和缩小。

EDIT2:环顾四周,我发现了这个链接:https ://wpf.2000things.com/tag/gridsplitter/

该链接中提到的一件事如下:

回想一下,在它自己的列中的 GridSplitter 并且将其 Horizo​​ntalAlignment 设置为 Center 将调整其任一侧的列的大小。在下面的示例中,调整了第 0 列和第 2 列的大小,但未更改第 3 列的宽度。

在我的测试中观察到的所有行为都符合该链接中提到的一个示例,所以我的新结论是这种行为都是故意的,而不是像我一直认为的那样是一个奇怪的错误。

于 2017-03-10T20:35:02.570 回答