WPF SharedSizeGroup GridSplitter Проблема
Я хочу использовать Grid для моего макета верхнего уровня. Сетка будет иметь 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>
3 ответа
Повторно разместив мой ответ от 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). Он работает с любым типом размеров (фиксированным, звездным и автоматическим) в любой комбинации.
ОБНОВЛЕНИЕ:
В качестве альтернативы и, возможно, лучше, вместо привязки к DataContext, вы можете сделать это исключительно в XAML. Просто определите одну основную сетку (не обязательно родительскую, но вам нужен какой-то способ ссылки на нее) с именованными столбцами, а затем привяжите их по имени.
<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>
Это добавило преимущество использования единого разветвителя сетки, совместно используемого всеми сетками.
Я могу повторить это и, честно говоря, это похоже на ошибку. Точнее говоря, если увеличить ширину столбца в первой строке, я не смогу уменьшить ширину дальше, чем эта ширина другой строки. Я собираюсь попробовать поиграть с этим еще немного, но... не уверен, что это исправит.
Попробуйте это решение, если оно вам подходит (в 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>
Надеюсь это поможет