WPF SharedSizeGroup GridSplitter Issue

蓝咒 提交于 2019-12-09 11:18:41

问题


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>

回答1:


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:


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.




回答3:


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



来源:https://stackoverflow.com/questions/1715124/wpf-sharedsizegroup-gridsplitter-issue

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!