none
Content に設定した要素をテンプレートで操作したい RRS feed

  • 質問

  • <Window
    
    	xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    
    	xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    
    	xmlns:Microsoft_Windows_Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
    
    	x:Class="WpfApplication1.MainWindow"
    
    	x:Name="Window"
    
    	Title="MainWindow"
    
    	Width="640" Height="480">
    
    
    
    	<Window.Resources>
    
    		<Style x:Key="ButtonFocusVisual">
    
    			<Setter Property="Control.Template">
    
    				<Setter.Value>
    
    					<ControlTemplate>
    
    						<Rectangle Stroke="Black" StrokeDashArray="1 2" StrokeThickness="1" Margin="2" SnapsToDevicePixels="true"/>
    
    					</ControlTemplate>
    
    				</Setter.Value>
    
    			</Setter>
    
    		</Style>
    
    		<LinearGradientBrush x:Key="ButtonNormalBackground" EndPoint="0,1" StartPoint="0,0">
    
    			<GradientStop Color="#F3F3F3" Offset="0"/>
    
    			<GradientStop Color="#EBEBEB" Offset="0.5"/>
    
    			<GradientStop Color="#DDDDDD" Offset="0.5"/>
    
    			<GradientStop Color="#CDCDCD" Offset="1"/>
    
    		</LinearGradientBrush>
    
    		<SolidColorBrush x:Key="ButtonNormalBorder" Color="#FF707070"/>
    
    		<Style x:Key="ButtonStyle1" TargetType="{x:Type Button}">
    
    			<Setter Property="FocusVisualStyle" Value="{StaticResource ButtonFocusVisual}"/>
    
    			<Setter Property="Background" Value="{StaticResource ButtonNormalBackground}"/>
    
    			<Setter Property="BorderBrush" Value="{StaticResource ButtonNormalBorder}"/>
    
    			<Setter Property="BorderThickness" Value="1"/>
    
    			<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    
    			<Setter Property="HorizontalContentAlignment" Value="Center"/>
    
    			<Setter Property="VerticalContentAlignment" Value="Center"/>
    
    			<Setter Property="Padding" Value="1"/>
    
    			<Setter Property="Template">
    
    				<Setter.Value>
    
    					<ControlTemplate TargetType="{x:Type Button}">
    
    						<Border x:Name="Border" Background="Red">
    
    							<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" RecognizesAccessKey="True"/>
    
    						</Border>
    
    						<ControlTemplate.Triggers>
    
    							<Trigger Property="IsMouseOver" Value="True">
    
    								<Setter TargetName="Border" Property="Background" Value="Blue"/>
    
    							</Trigger>
    
    						</ControlTemplate.Triggers>
    
    					</ControlTemplate>
    
    				</Setter.Value>
    
    			</Setter>
    
    		</Style>
    
    	</Window.Resources>
    
    
    
    	<Grid x:Name="LayoutRoot">
    
    		<Button Height="23" x:Name="button1" HorizontalAlignment="Center" VerticalAlignment="Center" Style="{DynamicResource ButtonStyle1}">
    
    			<Path x:Name="Path_1" Width="9" Height="Auto" Margin="7,8" Stretch="Fill" Fill="#FFEBEEF0" Data="F1 M 424.5,690.167L 420,683.167L 415.5,690.167L 424.5,690.167 Z "/>
    
    		</Button>
    
    	</Grid>
    
    </Window>
    
    
    Content に設定した Path 等 のコントロールをアニメーションや Trigger で変更させるにはどうしたらいいでしょうか?
    例えば,下に記述した Button の Content に設定した Path の色をマウスオーバーした時に黒色に変える,といった事を実現させたいです.
    • 編集済み フェイカー 2010年2月23日 7:07 表示の崩れを修正
    2010年2月23日 6:40

回答

  • Button.Content の中身は Button ごとに異なるわけで、Path じゃなくて Image かもしれないしってことになり、ControlTemplate で Content の中身を考えるのは筋が悪いでしょう。
    • Path.Fill は親 Button の Foreground に Binding して、ControlTemplate.Triggers で Button 自身の Foreground を変更する。
    • カスタムコントロールにしちゃって、Shape 型の ContentShape プロパティとか用意して、ControlTemplate では ContentPresenter 使わず直接 ContentShape を表示しちゃう。
    • ローカルにやるなら、Path の Style.Triggers で DataTrigger 使って親 Button の IsMouseOver が True になったときに自分の Fill を変更する。
    などを考えてみてはいかがでしょうか。
    2010年2月23日 10:23

すべての返信

  • Button.Content の中身は Button ごとに異なるわけで、Path じゃなくて Image かもしれないしってことになり、ControlTemplate で Content の中身を考えるのは筋が悪いでしょう。
    • Path.Fill は親 Button の Foreground に Binding して、ControlTemplate.Triggers で Button 自身の Foreground を変更する。
    • カスタムコントロールにしちゃって、Shape 型の ContentShape プロパティとか用意して、ControlTemplate では ContentPresenter 使わず直接 ContentShape を表示しちゃう。
    • ローカルにやるなら、Path の Style.Triggers で DataTrigger 使って親 Button の IsMouseOver が True になったときに自分の Fill を変更する。
    などを考えてみてはいかがでしょうか。
    2010年2月23日 10:23
  • Hongliang 様

    有難うございます.一番簡単そうな, "Foreground に Binding" で実現する事ができました.

    因みに,3 番目の方法の "親コントロールの IsMouseOver を..." を実現する為に親要素の
    Buttonを参照するには,以下の方法でよいのでしょうか?

    RelativeSource AncestorType={x:Type Button}, Mode=FindAncestor}
    2010年2月23日 14:30
  • RelativeSource AncestorType={x:Type Button}, Mode=FindAncestor}
    それが一番一般的でしょう。
    そのほかには ElementName で Name を参照するとかも可能です。
    2010年2月23日 14:38
  • 初歩的な質問にまでお答え下さり有難うございます.
    大変助かりました.
    2010年2月24日 1:00