ヘッダーがクリックされたときにWPFエキスパンダーが拡大するのを防ぐ
質問
WPFを防ぐにはどうすればよいですか Expander
ヘッダーがクリックされたときに拡大することから?私は欲しいです Expander
展開ボタン自体がクリックされた場合にのみ展開または崩壊します。
答えは、泡立ったイベントをキャンセルすることと関係があると思います。可能であれば、全体を再表示することを避けながら、XAMLにソリューションを実装したいと思います Expander
.
解決
ヘッダーはイベントを作成するボタンなので、エキスパンダーのテンプレートを変更して、エキスパンダーアイコンをボタンとして変更する必要があります。
これが投稿です エキスパンダーを変更する方法.
他のヒント
実際、テンプレートを変更するよりもはるかにシンプルなXAMLソリューションがあります。この場合、Expanderのヘッダープロパティを使用しないでください。代わりに、独自のスタイルのテキストブロックでエキスパンダーを覆います。
<Application.Resources>
<Style x:Key="ExpanderHeader" TargetType="{x:Type TextBlock}">
<Setter Property="Height" Value="22" />
<Setter Property="Margin" Value="21,0,0,0" />
<Setter Property="Padding" Value="9,3,0,0" />
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="VerticalAlignment" Value="Top" />
</Style>
</Application.Resources>
<Grid>
<Expander>
<TextBlock Text="I am some content. I have disowned my default header." Margin="10,5" />
</Expander>
<TextBlock Text="I'm filling in for the default header. You'll like me better anyway."
Style="{StaticResource ResourceKey=ExpanderHeader}"/>
</Grid>
私の解決策は、ヘッダーを空白のままにして、ヘッダーとして機能するコントロールにタグを付けることでした(絶対的な位置付けにキャンバスを使用して)、アイコンのみがコントロールを展開します。
<Grid Height="{Binding ElementName=exp, Path=ActualHeight}">
<Canvas>
<Expander Name="exp">
...
</Expander>
<Control Style="{StaticResource ExpanderHeaderStyle}" Margin="20,0,0,0" />
</Canvas>
</Grid>
デフォルトのテンプレートを変更しました Expander
Simeonが提案した制御。
以下 ControlTemplate
ユーザーがヘッダーアイコンをクリックしたときにのみ反応する(拡張/崩壊する)エキスパンダーを定義します。
これは迅速で汚れているので、壊れることを期待してください。
<ControlTemplate x:Key="LazyExpanderTemplate" TargetType="Expander">
<Border BorderThickness="{TemplateBinding Border.BorderThickness}" CornerRadius="3,3,3,3" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" SnapsToDevicePixels="True">
<DockPanel>
<DockPanel DockPanel.Dock="Top" Name="HeaderSite">
<ToggleButton
DockPanel.Dock="Left"
IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsExpanded}"
Foreground="{TemplateBinding TextElement.Foreground}"
FontFamily="{TemplateBinding TextElement.FontFamily}"
FontSize="{TemplateBinding TextElement.FontSize}"
FontStretch="{TemplateBinding TextElement.FontStretch}"
FontStyle="{TemplateBinding TextElement.FontStyle}"
FontWeight="{TemplateBinding TextElement.FontWeight}"
HorizontalContentAlignment="{TemplateBinding Control.HorizontalContentAlignment}"
VerticalContentAlignment="{TemplateBinding Control.VerticalContentAlignment}"
Padding="{TemplateBinding Control.Padding}"
MinWidth="0"
MinHeight="0"
Margin="1,1,1,1"
>
<ToggleButton.Style>
<Style TargetType="ToggleButton">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="{TemplateBinding Control.Padding}">
<Grid Background="#00FFFFFF" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Ellipse Stroke="#FFA9A9A9" Name="circle" Width="19" Height="19" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Ellipse Name="shadow" Width="17" Height="17" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden" />
<Path Data="M1,1.5L4.5,5 8,1.5" Stroke="#FF666666" StrokeThickness="2" Name="arrow" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="False" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked" Value="True" >
<Setter Property="Path.Data" TargetName="arrow">
<Setter.Value>
<StreamGeometry>M1,4.5L4.5,1 8,4.5</StreamGeometry>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="UIElement.IsMouseOver" Value="True">
<Setter Property="Shape.Stroke" TargetName="circle">
<Setter.Value>
<SolidColorBrush>#FF666666</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Shape.Stroke" TargetName="arrow">
<Setter.Value>
<SolidColorBrush>#FF222222</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="UIElement.Visibility" TargetName="shadow">
<Setter.Value>
<x:Static Member="Visibility.Visible" />
</Setter.Value>
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.Style>
<ToggleButton.FocusVisualStyle>
<Style TargetType="IFrameworkInputElement">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<Rectangle Stroke="#FF000000" StrokeThickness="1" StrokeDashArray="1 2" Margin="0,0,0,0" SnapsToDevicePixels="True" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ToggleButton.FocusVisualStyle>
</ToggleButton>
<ContentPresenter
RecognizesAccessKey="True"
Content="{TemplateBinding HeaderedContentControl.Header}"
ContentTemplate="{TemplateBinding HeaderedContentControl.HeaderTemplate}"
ContentStringFormat="{TemplateBinding HeaderedContentControl.HeaderStringFormat}"
Margin="4,0,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
SnapsToDevicePixels="True"
/>
</DockPanel>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Name="ExpandSite" Margin="{TemplateBinding Control.Padding}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" Visibility="Collapsed" Focusable="False" DockPanel.Dock="Bottom" />
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="Expander.IsExpanded">
<Setter Property="UIElement.Visibility" TargetName="ExpandSite">
<Setter.Value>
<x:Static Member="Visibility.Visible" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
<Trigger Property="Expander.ExpandDirection" Value="Right">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Right"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Left"/>
<Setter Property="FrameworkElement.Style" TargetName="HeaderSite">
<Setter.Value>
<Style TargetType="ToggleButton">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="{TemplateBinding Control.Padding}">
<Grid Background="#00FFFFFF" SnapsToDevicePixels="False">
<Grid.RowDefinitions>
<RowDefinition Height="19" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="-90" />
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse Stroke="#FFA9A9A9" Name="circle" Width="19" Height="19" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Ellipse Name="shadow" Width="17" Height="17" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden" />
<Path Data="M1,1.5L4.5,5 8,1.5" Stroke="#FF666666" StrokeThickness="2" Name="arrow" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="False" />
</Grid>
<ContentPresenter RecognizesAccessKey="True" Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Margin="0,4,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" SnapsToDevicePixels="True" Grid.Row="1" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked">
<Setter Property="Path.Data" TargetName="arrow">
<Setter.Value>
<StreamGeometry>M1,4.5L4.5,1 8,4.5</StreamGeometry>
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
<Trigger Property="UIElement.IsMouseOver">
<Setter Property="Shape.Stroke" TargetName="circle">
<Setter.Value>
<SolidColorBrush>#FF666666</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Shape.Stroke" TargetName="arrow">
<Setter.Value>
<SolidColorBrush>#FF222222</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="UIElement.Visibility" TargetName="shadow">
<Setter.Value>
<x:Static Member="Visibility.Visible" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
</Trigger>
<Trigger Property="Expander.ExpandDirection">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite" Value="Top"/>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite" Value="Bottom"/>
<Setter Property="FrameworkElement.Style" TargetName="HeaderSite">
<Setter.Value>
<Style TargetType="ToggleButton">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="{TemplateBinding Control.Padding}">
<Grid Background="#00FFFFFF" SnapsToDevicePixels="False">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="19" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="180" />
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse Stroke="#FFA9A9A9" Name="circle" Width="19" Height="19" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Ellipse Name="shadow" Width="17" Height="17" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden" />
<Path Data="M1,1.5L4.5,5 8,1.5" Stroke="#FF666666" StrokeThickness="2" Name="arrow" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="False" />
</Grid>
<ContentPresenter RecognizesAccessKey="True" Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Margin="4,0,0,0" HorizontalAlignment="Left" VerticalAlignment="Center" SnapsToDevicePixels="True" Grid.Column="1" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked">
<Setter Property="Path.Data" TargetName="arrow">
<Setter.Value>
<StreamGeometry>M1,4.5L4.5,1 8,4.5</StreamGeometry>
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
<Trigger Property="UIElement.IsMouseOver">
<Setter Property="Shape.Stroke" TargetName="circle">
<Setter.Value>
<SolidColorBrush>#FF666666</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Shape.Stroke" TargetName="arrow">
<Setter.Value>
<SolidColorBrush>#FF222222</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="UIElement.Visibility" TargetName="shadow">
<Setter.Value>
<x:Static Member="Visibility.Visible" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Trigger.Value>
<x:Static Member="ExpandDirection.Up" />
</Trigger.Value>
</Trigger>
<Trigger Property="Expander.ExpandDirection">
<Setter Property="DockPanel.Dock" TargetName="ExpandSite">
<Setter.Value>
<x:Static Member="Dock.Left" />
</Setter.Value>
</Setter>
<Setter Property="DockPanel.Dock" TargetName="HeaderSite">
<Setter.Value>
<x:Static Member="Dock.Right" />
</Setter.Value>
</Setter>
<Setter Property="FrameworkElement.Style" TargetName="HeaderSite">
<Setter.Value>
<Style TargetType="ToggleButton">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="ToggleButton">
<Border Padding="{TemplateBinding Control.Padding}">
<Grid Background="#00FFFFFF" SnapsToDevicePixels="False">
<Grid.RowDefinitions>
<RowDefinition Height="19" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid>
<Grid.LayoutTransform>
<TransformGroup>
<TransformGroup.Children>
<RotateTransform Angle="90" />
</TransformGroup.Children>
</TransformGroup>
</Grid.LayoutTransform>
<Ellipse Stroke="#FFA9A9A9" Name="circle" Width="19" Height="19" HorizontalAlignment="Center" VerticalAlignment="Center" />
<Ellipse Name="shadow" Width="17" Height="17" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="Hidden" />
<Path Data="M1,1.5L4.5,5 8,1.5" Stroke="#FF666666" StrokeThickness="2" Name="arrow" HorizontalAlignment="Center" VerticalAlignment="Center" SnapsToDevicePixels="False" />
</Grid>
<ContentPresenter RecognizesAccessKey="True" Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Margin="0,4,0,0" HorizontalAlignment="Center" VerticalAlignment="Top" SnapsToDevicePixels="True" Grid.Row="1" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="ToggleButton.IsChecked">
<Setter Property="Path.Data" TargetName="arrow">
<Setter.Value>
<StreamGeometry>M1,4.5L4.5,1 8,4.5</StreamGeometry>
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
<Trigger Property="UIElement.IsMouseOver">
<Setter Property="Shape.Stroke" TargetName="circle">
<Setter.Value>
<SolidColorBrush>#FF666666</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="Shape.Stroke" TargetName="arrow">
<Setter.Value>
<SolidColorBrush>#FF222222</SolidColorBrush>
</Setter.Value>
</Setter>
<Setter Property="UIElement.Visibility" TargetName="shadow">
<Setter.Value>
<x:Static Member="Visibility.Visible" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>True</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
<Trigger.Value>
<x:Static Member="ExpandDirection.Left" />
</Trigger.Value>
</Trigger>
<Trigger Property="UIElement.IsEnabled">
<Setter Property="TextElement.Foreground">
<Setter.Value>
<DynamicResource ResourceKey="{x:Static SystemColors.GrayTextBrushKey}" />
</Setter.Value>
</Setter>
<Trigger.Value>
<s:Boolean>False</s:Boolean>
</Trigger.Value>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
かなり簡単な解決策は、Expander Control Tempateが次の方法で使用するトグルボタンテンプレートを変更することです。
- グリッドと境界の背景を{x:null}に設定します
Content Presenterをfalseに設定します
<ControlTemplate TargetType="{x:Type ToggleButton}"> <Border Padding="{TemplateBinding Padding}" Background="{x:Null}"> <Grid Background="{x:Null}" SnapsToDevicePixels="False"> <Grid.RowDefinitions> <RowDefinition Height="19"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid> <Grid.LayoutTransform> <TransformGroup> <TransformGroup.Children> <TransformCollection> <RotateTransform Angle="-90"/> </TransformCollection> </TransformGroup.Children> </TransformGroup> </Grid.LayoutTransform> <Ellipse x:Name="circle" HorizontalAlignment="Center" Height="19" Stroke="DarkGray" VerticalAlignment="Center" Width="19"/> <Path x:Name="arrow" Data="M 1,1.5 L 4.5,5 L 8,1.5" HorizontalAlignment="Center" SnapsToDevicePixels="false" Stroke="#666" StrokeThickness="2" VerticalAlignment="Center"/> </Grid> <ContentPresenter HorizontalAlignment="Center" Margin="0,4,0,0" Grid.Row="1" RecognizesAccessKey="True" SnapsToDevicePixels="True" VerticalAlignment="Top"IsHitTestVisible="False"/> </Grid> </Border> </ControlTemplate>
IsEnabledをfalseに設定するだけですが、ヘッダーがクリックされたときに拡張または崩壊できるかどうかを判断する必要がある場合には:
public class MyExpander : Expander
{
private bool CanExpand() => true;
private bool CanCollapse() => true;
private bool rollback;
protected override void OnExpanded()
{
if (rollback) return;
if (CanExpand())
{
base.OnExpanded();
}
else
{
rollback = true;
SetCurrentValue(IsExpandedProperty, false);
rollback = false;
}
}
protected override void OnCollapsed()
{
if (rollback) return;
if (CanCollapse())
{
base.OnCollapsed();
}
else
{
rollback = true;
SetCurrentValue(IsExpandedProperty, true);
rollback = false;
}
}
}