GridSplitter 在移动到外部资源(UserControl)时表现不同
GridSplitter acts differently when moved to external resource (UserControl)
由于我的 WPF 应用程序多次使用 GridSplitter
,我想将 XAML 片段提取到单独的 UserControl
.
当然,使用ResourceDictionary
会更好。但是那样的话,我只能为拆分器的内容定义一个 ControlTemplate
,然后在 Template
- 属性中使用它 - 这样就无法定义所有这些 GridSplitter
属性一次又一次连续使用它们。
GridSplitter
UserControl
, GridSplitter.xaml:
<GridSplitter HorizontalAlignment="Stretch" Margin="3" ResizeBehavior="PreviousAndNext"
ResizeDirection="Columns" VerticalAlignment="Stretch">
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Grid>
<Button Content="⁞" />
<Rectangle Fill="#00FFFFFF" />
</Grid>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter>
MainWindow.xaml中的用法:
<Window
(...)
xmlns:uc="clr-namespace:Yoda.Frontend.Resources"
(...)>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition MinWidth="400" Width="*" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<uc:GridSplitter Grid.Column="1" />
<!-- (...) -->
</Grid>
<!-- (...) -->
</Window>
使用上述代码的结果是无法向任何方向移动的拆分器。
但是,使用上面提到的 ResourceDictionary
字典方法,我得到了一个可移动的 GridSplitter
。
但是尽管直接在 MainWindow.xaml 中完美地工作,它只调整第三个网格列的大小。
当然,在使用 GridSplitter
时不建议设置 Width
。但是,为什么只要拆分器在主 window 中定义,它就可以工作,而只有在用作 UserControl
时才会这样做?以及如何在 MVVM 中解决这个问题,没有代码隐藏方式?
如果你只是想要一个漂亮的分离器,你可以使用这个代码:
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="Auto" />
<ColumnDefinition MinWidth="20" Width="Auto" />
<ColumnDefinition MinWidth="400" Width="Auto" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<GridSplitter Grid.Column="1" Background="Gray" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<TextBlock Text="⁞" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"
IsHitTestVisible="False" />
<!-- (...) -->
另一种解决方案是将 ControlTemplate
定义为资源,然后将其用于 GridSplitter
:
<Window.Resources>
<ControlTemplate TargetType="{x:Type GridSplitter}" x:Key="gridSplitter">
<Grid Background="Transparent">
<Button Content="⁞" IsHitTestVisible="False" />
<Rectangle Fill="#00FFFFFF" IsHitTestVisible="False" />
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="Auto" />
<ColumnDefinition MinWidth="20" Width="Auto" />
<ColumnDefinition MinWidth="400" Width="Auto" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<GridSplitter Grid.Column="1" Template="{StaticResource gridSplitter}" />
<!-- (...) -->
</Grid>
<!-- (...) -->
</Grid>
如果您真的想在拆分器模板中使用设置属性,还有一个解决方案:使用样式来添加这些属性。它看起来像这样:
<Window.Resources>
<ControlTemplate TargetType="{x:Type GridSplitter}" x:Key="gridSplitter">
<Grid Background="Transparent">
<Button Content="⁞" IsHitTestVisible="False"/>
<Rectangle Fill="#00FFFFFF" IsHitTestVisible="False"/>
</Grid>
</ControlTemplate>
<Style TargetType="{x:Type GridSplitter}" x:Key="styleGridSplitter">
<Setter Property="Template" Value="{StaticResource gridSplitter}" />
<Setter Property="ResizeBehavior" Value="PreviousAndNext" />
<Setter Property="ResizeDirection" Value="Columns" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Margin" Value="3" />
</Style>
</Window.Resources>
<Grid>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="Auto" />
<ColumnDefinition MinWidth="20" Width="Auto" />
<ColumnDefinition MinWidth="400" Width="Auto" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<GridSplitter Grid.Column="1" Style="{StaticResource styleGridSplitter}"/>
<!-- (...) -->
</Grid>
<!-- (...) -->
</Grid>
由于我的 WPF 应用程序多次使用 GridSplitter
,我想将 XAML 片段提取到单独的 UserControl
.
当然,使用ResourceDictionary
会更好。但是那样的话,我只能为拆分器的内容定义一个 ControlTemplate
,然后在 Template
- 属性中使用它 - 这样就无法定义所有这些 GridSplitter
属性一次又一次连续使用它们。
GridSplitter
UserControl
, GridSplitter.xaml:
<GridSplitter HorizontalAlignment="Stretch" Margin="3" ResizeBehavior="PreviousAndNext"
ResizeDirection="Columns" VerticalAlignment="Stretch">
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Grid>
<Button Content="⁞" />
<Rectangle Fill="#00FFFFFF" />
</Grid>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter>
MainWindow.xaml中的用法:
<Window
(...)
xmlns:uc="clr-namespace:Yoda.Frontend.Resources"
(...)>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="200" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition MinWidth="400" Width="*" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<uc:GridSplitter Grid.Column="1" />
<!-- (...) -->
</Grid>
<!-- (...) -->
</Window>
使用上述代码的结果是无法向任何方向移动的拆分器。
但是,使用上面提到的 ResourceDictionary
字典方法,我得到了一个可移动的 GridSplitter
。
但是尽管直接在 MainWindow.xaml 中完美地工作,它只调整第三个网格列的大小。
当然,在使用 GridSplitter
时不建议设置 Width
。但是,为什么只要拆分器在主 window 中定义,它就可以工作,而只有在用作 UserControl
时才会这样做?以及如何在 MVVM 中解决这个问题,没有代码隐藏方式?
如果你只是想要一个漂亮的分离器,你可以使用这个代码:
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="Auto" />
<ColumnDefinition MinWidth="20" Width="Auto" />
<ColumnDefinition MinWidth="400" Width="Auto" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<GridSplitter Grid.Column="1" Background="Gray" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
<TextBlock Text="⁞" Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"
IsHitTestVisible="False" />
<!-- (...) -->
另一种解决方案是将 ControlTemplate
定义为资源,然后将其用于 GridSplitter
:
<Window.Resources>
<ControlTemplate TargetType="{x:Type GridSplitter}" x:Key="gridSplitter">
<Grid Background="Transparent">
<Button Content="⁞" IsHitTestVisible="False" />
<Rectangle Fill="#00FFFFFF" IsHitTestVisible="False" />
</Grid>
</ControlTemplate>
</Window.Resources>
<Grid>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="Auto" />
<ColumnDefinition MinWidth="20" Width="Auto" />
<ColumnDefinition MinWidth="400" Width="Auto" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<GridSplitter Grid.Column="1" Template="{StaticResource gridSplitter}" />
<!-- (...) -->
</Grid>
<!-- (...) -->
</Grid>
如果您真的想在拆分器模板中使用设置属性,还有一个解决方案:使用样式来添加这些属性。它看起来像这样:
<Window.Resources>
<ControlTemplate TargetType="{x:Type GridSplitter}" x:Key="gridSplitter">
<Grid Background="Transparent">
<Button Content="⁞" IsHitTestVisible="False"/>
<Rectangle Fill="#00FFFFFF" IsHitTestVisible="False"/>
</Grid>
</ControlTemplate>
<Style TargetType="{x:Type GridSplitter}" x:Key="styleGridSplitter">
<Setter Property="Template" Value="{StaticResource gridSplitter}" />
<Setter Property="ResizeBehavior" Value="PreviousAndNext" />
<Setter Property="ResizeDirection" Value="Columns" />
<Setter Property="VerticalAlignment" Value="Stretch" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Margin" Value="3" />
</Style>
</Window.Resources>
<Grid>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="Blue">
<Grid.ColumnDefinitions>
<ColumnDefinition MinWidth="100" Width="Auto" />
<ColumnDefinition MinWidth="20" Width="Auto" />
<ColumnDefinition MinWidth="400" Width="Auto" />
</Grid.ColumnDefinitions>
<!-- (...) -->
<GridSplitter Grid.Column="1" Style="{StaticResource styleGridSplitter}"/>
<!-- (...) -->
</Grid>
<!-- (...) -->
</Grid>