WPF共享大小组GridSplitter问题

8
我希望使用一个网格作为我的顶层布局。该网格将有1列和n行。每个网格中的每一行也应包含一个网格,该网格应具有3列和1行。在第二列中是一个GridSplitter,我正在尝试使用SharedSizeGroup,以便它可以跨所有嵌套网格更改第一列的大小。
这是我所拥有的...而且它起作用了!!...好吧,有点...如果你点击分隔器并调整大小而不松开它,它会起作用...但出于某种原因,如果你调整大小并松开鼠标,然后尝试使用不同的行进行调整大小,它似乎会"卡住"。
有什么想法吗?
<!-- Parent Grid -->
<Grid Grid.IsSharedSizeScope="True">
    <Grid.RowDefinitions>
        <RowDefinition></RowDefinition>
        <RowDefinition></RowDefinition>
    </Grid.RowDefinitions>

    <!-- First Grid -->
    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A" Width="Auto"></ColumnDefinition>
            <ColumnDefinition SharedSizeGroup="B" Width="Auto"></ColumnDefinition>
            <ColumnDefinition SharedSizeGroup="C" Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0">One-Left</Label>
        <GridSplitter Grid.Column="1" Width="5" Background="DarkGray"></GridSplitter>
        <Label Grid.Column="2">One-Right</Label>
    </Grid>

    <!-- Second Grid -->
    <Grid Grid.Row="1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="A" Width="Auto"></ColumnDefinition>
            <ColumnDefinition SharedSizeGroup="B" Width="Auto"></ColumnDefinition>
            <ColumnDefinition SharedSizeGroup="C" Width="Auto"></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <Label Grid.Column="0">Two-Left</Label>
        <GridSplitter Grid.Column="1" Width="5" Background="DarkGray"></GridSplitter>
        <Label Grid.Column="2">Two-Right</Label>
    </Grid>

</Grid>

我也尝试在带有.NET 4.0的VS2010 beta 2中执行此操作,并遇到了相同的问题。 - pmcilreavy
如果是这种情况,你应该立即在Microsoft Connect上报告此错误。他们仍有机会在4.0中修复它! - Drew Marsh
尝试在所有子网格上使用GridSplitter,看看我的答案,希望这有所帮助。 - punker76
当有多个网格分隔条的网格单元格属于相同大小范围时,似乎会发生这种情况。 - Ugo Robain
3个回答

12

以下是我从 ms connect 转载的答案:

通常情况下,您可以通过不使用 SharedSizeGroup,而是将所有共享大小绑定到一个对象的单个属性(例如,您的 DataContext)来解决此问题:

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:my="clr-namespace:WpfApplication3"
        Height="350" Width="525" Title="MainWindow">

    <Window.DataContext>
        <my:MainWindowData Width0="1*" Width1="1*" />
    </Window.DataContext>

    <Window.Resources>

        <DataTemplate x:Key="dt">
         <Grid>
            <Grid.ColumnDefinitions>
             <ColumnDefinition Width="{Binding Path=Width0, Mode=TwoWay}" />
             <ColumnDefinition Width="Auto" />
             <ColumnDefinition Width="{Binding Path=Width1, Mode=TwoWay}" />
            </Grid.ColumnDefinitions>
            <Button Grid.Column="0" Content="{Binding Width0}" />
            <GridSplitter Grid.Column="1" Width="10" ResizeBehavior="PreviousAndNext" ResizeDirection="Columns" />
            <Button Grid.Column="2" Content="{Binding Width1}" />
         </Grid>
        </DataTemplate>

    </Window.Resources>

    <StackPanel>
        <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource dt}" />
        <ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource dt}" />
    </StackPanel>

</Window>

Width0和Width1必须是匹配类型(GridLength)。它适用于任何大小类型(固定、星形和自动)的任何组合。

更新:

或者,也可以纯粹在XAML中完成而不是绑定到DataContext。只需定义一个带有命名列的单个主网格(不一定是父级,但需要某种引用方式),然后按名称进行绑定。

<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Height="350" Width="525" Title="MainWindow">

    <!-- shared sizing used only on fixed size columns therefore safe -->
    <!-- alternatively you can hardcode width of splitter column -->
    <Grid Name="masterGrid" Grid.IsSharedSizeScope="True">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" Name="masterColumn0" />
            <ColumnDefinition Width="Auto" SharedSizeGroup="masterColumn1" />
            <ColumnDefinition Width="1*" Name="masterColumn2" />
        </Grid.ColumnDefinitions>
        <StackPanel Grid.ColumnSpan="3">
            <StackPanel.Resources>
                <DataTemplate x:Key="dt">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="{Binding Path=Width, Mode=TwoWay, ElementName=masterColumn0}" />
                            <ColumnDefinition Width="Auto" SharedSizeGroup="masterColumn1" />
                            <ColumnDefinition Width="{Binding Path=Width, Mode=TwoWay, ElementName=masterColumn2}" />
                        </Grid.ColumnDefinitions>
                        <Button Grid.Column="0" Content="{Binding Path=Width, Mode=TwoWay, ElementName=masterColumn0}" />
                        <Button Grid.Column="2" Content="{Binding Path=Width, Mode=TwoWay, ElementName=masterColumn2}" />
                    </Grid>
                </DataTemplate>
            </StackPanel.Resources>
            <ContentPresenter ContentTemplate="{StaticResource dt}" />
            <ContentPresenter ContentTemplate="{StaticResource dt}" />
        </StackPanel>
        <GridSplitter Grid.Column="1" Width="10" ResizeBehavior="PreviousAndNext" ResizeDirection="Columns" ShowsPreview="True" />
    </Grid>

</Window>

这样做的好处是使用一个单独的网格分隔器,由所有网格共享。


3

我能够重现这个问题,老实说,它看起来像一个bug。具体来说,如果扩展第一行的列宽,我就无法将其他行的列宽缩小到该列宽以下。我会继续尝试调整,但是......不确定应该如何解决。


谢谢回复。这正是我所想的。它似乎应该可以工作,而且有点工作了...但也完全不行。这让我疯狂!! - pmcilreavy

1

如果您觉得可以的话,可以尝试这个解决方案(在Kaxaml中它运行良好)。

<!-- Parent Grid -->
<Grid Grid.IsSharedSizeScope="True">

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

  <Grid.ColumnDefinitions>
    <ColumnDefinition SharedSizeGroup="A" Width="Auto"></ColumnDefinition>
    <ColumnDefinition Width="Auto"></ColumnDefinition>
    <ColumnDefinition SharedSizeGroup="C" Width="Auto"></ColumnDefinition>
  </Grid.ColumnDefinitions>

  <Label Grid.Column="0" Grid.Row="0">One-Left</Label>
  <Label Grid.Column="0" Grid.Row="1">Two-Left</Label>
  <GridSplitter Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Width="5" Background="DarkGray"></GridSplitter>
  <Label Grid.Column="2" Grid.Row="0">One-Right</Label>
  <Label Grid.Column="2" Grid.Row="1">Two-Right</Label>

</Grid>

希望这能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接