7
votes

I wish to use a Grid for my top level layout. The Grid will have 1 column and n rows. Each row in the Grid should also contain a Grid which shall have 3 columns and 1 row. In the second column is a GridSplitter and I am trying to use a SharedSizeGroup so that this changes the size of the first column across all of the nested Grids.

Here is what i have...and it works!!...well kind of...if you click the splitter and resize without letting go it works...but for some reason if you resize something and let go of the mouse and then attempt to resize using a different row it seems to "stick".

Any ideas?

<!-- 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>
3
Have also tried this in VS2010 beta 2 with .net 4.0 and get the same issue.pmcilreavy
If that's the case you should report this bug on Microsoft Connect immediately. There's still a chance they can fix it in 4.0!!!Drew Marsh
try using a gridplitter over all your subgrids, look at my answer, hope this helpspunker76
It seems to happens when there is more than one gridsplitter whose grid cells are part of the same size scope.Ugo Robain

3 Answers

11
votes

Reposting my answer from ms connect:

You can usually work around this by not using SharedSizeGroup and instead binding all shared sizes to single property on one object (eg. your 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>

Where Width0 and Width1 are of matching type (GridLength). It works with any kind of sizing (fixed, star and auto) in any combination.

UPDATE:

Alternatively and perhaps better, instead of binding to DataContext, you can do it purely in XAML. Just define a single master grid (not necessarily a parent but you need some way to reference it) with named columns then bind to them by name.

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

This has added benefit of using a single grid splitter shared by all grids.

2
votes

I am able to repro this and, honestly, it looks like a bug. To be specific, if expand the width of the column in row one, I'm unable to reduce the width any further than that width another row. I'm going to try and play with this one some more, but... not sure what would fix that.

1
votes

try this solution if it's ok for you (at Kaxaml it works fine).

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

Hope this helps