Wpf 如何根据XAML中的目标控件属性调整ControlTemplate参数?
我有两个Wpf 如何根据XAML中的目标控件属性调整ControlTemplate参数?,wpf,xaml,Wpf,Xaml,我有两个GridSplitters,一个垂直: <GridSplitter Grid.Column="1" ResizeDirection="Columns" VerticalAlignment="Stretch" Background="Transparent" Template="{StaticResource GridSplitterTemplate}"/> 和一个横向: <GridSplitter Grid.Row="1" Resiz
GridSplitter
s,一个垂直:
<GridSplitter Grid.Column="1" ResizeDirection="Columns" VerticalAlignment="Stretch"
Background="Transparent" Template="{StaticResource GridSplitterTemplate}"/>
和一个横向:
<GridSplitter Grid.Row="1" ResizeDirection="Rows" HorizontalAlignment="Stretch"
Background="Transparent" Template="{StaticResource GridSplitterTemplate}"/>
我使用此模板为它们提供所需的外观:
<Window.Resources>
<ControlTemplate x:Key="GridSplitterTemplate" TargetType="{x:Type GridSplitter}">
<ControlTemplate.Resources>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Black"/>
<Setter Property="Height" Value="5"/>
<Setter Property="Width" Value="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"/>
<Setter Property="Margin" Value="1,3"/>
<!-- Or:
<Setter Property="Margin" Value="3,1"/>
-->
</Style>
</ControlTemplate.Resources>
<Grid>
<Grid.Style>
<Style>
<Style.Triggers>
<Trigger Property="Grid.IsMouseOver" Value="True">
<Setter Property="Grid.Background" Value="DarkGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Rectangle Fill="#00FF00FF">
<!-- Completely transparent, just to fill the space -->
</Rectangle>
<!-- Orientation="Horizontal" if it's horizontal... -->
<StackPanel Orientation="Vertical" VerticalAlignment="Center" HorizontalAlignment="Center">
<!--<StackPanel.Style>
<Style>
<Style.Triggers>
<Trigger Property="GridSplitter.ResizeDirection" Value="Rows">
</Trigger>
</Style.Triggers>
</Style>
</StackPanel.Style>-->
<Ellipse/>
<Ellipse/>
<Ellipse/>
</StackPanel>
</Grid>
</ControlTemplate>
</Window.Resources>
问题是此模板仅对水平网格拆分器有效。我必须复制整个模板才能更改两个字段(StackPanel
的方向和
标记中的边距值)
是否有一种方法可以根据GridSplitter
的ResizeDirection
来调节这些模板值?好的,知道了,使用DataTrigger
s:
<ControlTemplate x:Key="GridSplitterTemplate" TargetType="{x:Type GridSplitter}">
<ControlTemplate.Resources>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Black"/>
<Setter Property="Height" Value="5"/>
<Setter Property="Width" Value="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"/>
<!--<Setter Property="Margin" Value="3,1"/>-->
<Style.Triggers>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Rows">
<Setter Property="Margin" Value="3,1"/>
</DataTrigger>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Columns">
<Setter Property="Margin" Value="1,3"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ControlTemplate.Resources>
<Grid>
<Grid.Style>
<Style>
<Style.Triggers>
<Trigger Property="Grid.IsMouseOver" Value="True">
<Setter Property="Grid.Background" Value="DarkGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Rectangle Fill="#00FF00FF">
<!-- Completely transparent, just to fill the space -->
</Rectangle>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Rows">
<Setter Property="StackPanel.Orientation" Value="Horizontal"/>
</DataTrigger>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Columns">
<Setter Property="StackPanel.Orientation" Value="Vertical"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Ellipse/>
<Ellipse/>
<Ellipse/>
</StackPanel>
</Grid>
</ControlTemplate>
好的,明白了,使用DataTrigger
s:
<ControlTemplate x:Key="GridSplitterTemplate" TargetType="{x:Type GridSplitter}">
<ControlTemplate.Resources>
<Style TargetType="Ellipse">
<Setter Property="Fill" Value="Black"/>
<Setter Property="Height" Value="5"/>
<Setter Property="Width" Value="{Binding Path=ActualHeight, RelativeSource={RelativeSource Self}}"/>
<!--<Setter Property="Margin" Value="3,1"/>-->
<Style.Triggers>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Rows">
<Setter Property="Margin" Value="3,1"/>
</DataTrigger>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Columns">
<Setter Property="Margin" Value="1,3"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ControlTemplate.Resources>
<Grid>
<Grid.Style>
<Style>
<Style.Triggers>
<Trigger Property="Grid.IsMouseOver" Value="True">
<Setter Property="Grid.Background" Value="DarkGray"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</Grid.Style>
<Rectangle Fill="#00FF00FF">
<!-- Completely transparent, just to fill the space -->
</Rectangle>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center">
<StackPanel.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Rows">
<Setter Property="StackPanel.Orientation" Value="Horizontal"/>
</DataTrigger>
<DataTrigger Binding="{Binding ResizeDirection, RelativeSource={RelativeSource FindAncestor, AncestorType=GridSplitter}}" Value="Columns">
<Setter Property="StackPanel.Orientation" Value="Vertical"/>
</DataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Style>
<Ellipse/>
<Ellipse/>
<Ellipse/>
</StackPanel>
</Grid>
</ControlTemplate>
两种可能的方法:
使用IValueConverters
将StackPanel的方向和边距绑定到ResizeDirection
属性
子类“GridSplitter”,并为方向和边距添加新的依赖属性
Edit3.对于WPF,我没有想到的最好的方法是使用DataTrigger
第一个选项似乎更简单。只需使用转换器将orientation属性绑定到TemplatedParent->ResizeDirection:
<StackPanel Orientation="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=ResizeDirection,
Converter={StaticResource ResizeDirectionToOrientationConverter}}">
两种可能的方法:
使用IValueConverters
将StackPanel的方向和边距绑定到ResizeDirection
属性
子类“GridSplitter”,并为方向和边距添加新的依赖属性
Edit3.对于WPF,我没有想到的最好的方法是使用DataTrigger
第一个选项似乎更简单。只需使用转换器将orientation属性绑定到TemplatedParent->ResizeDirection:
<StackPanel Orientation="{Binding RelativeSource={RelativeSource TemplatedParent},
Path=ResizeDirection,
Converter={StaticResource ResizeDirectionToOrientationConverter}}">