如何在WPF中获取子属性?

时间:2015-10-21 18:10:41

标签: c# wpf xaml

我想写一个触发器,它会改变属性" Offset"当鼠标悬停在按钮上时。当我尝试这样的时候:

 <ControlTemplate x:Key="Button">
            <Grid x:Name="button">
                <Rectangle x:Name="ButtonTheme" RadiusX="10" RadiusY="10" Stroke="Silver" StrokeThickness="3" Fill="{TemplateBinding Background}"></Rectangle>
                <Rectangle x:Name="HighLight" Opacity="1.0">
                    <Rectangle.Fill>
                        <RadialGradientBrush Center="0.5,0.8">
                            <GradientStop x:Name="Flower" Color="#AAFFFFFF" Offset="1" />
                            <GradientStop Color="#00FFFFFF" Offset="0" />
                        </RadialGradientBrush>
                    </Rectangle.Fill>
                </Rectangle>
                <ContentControl HorizontalAlignment="Center"
                                VerticalAlignment="Center"
                                Content= "{TemplateBinding Property = ContentControl.Content}" />
                 </Grid>
            <ControlTemplate.Triggers>
                <Trigger Property="Button.IsMouseOver" Value="True">
                    <Setter TargetName="Flower" Property="Offset" Value="1" />
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate> 

它返回&#34;姓名为#34; Flower&#34;在Visual Tree&#34;中找不到。有没有办法改变这个属性?

1 个答案:

答案 0 :(得分:0)

错误清楚地说明了什么是错的。 GradientStop不是视觉树的一部分,它不是视觉树。而且我认为这是XAML的某种限制,最好是轻松做你做的事情。

为了坚持你现在拥有的代码,我们只能使用一个hacky解决方案,我们将GradientStop的Offset绑定到一些 已知的 元素属性。 (此处 已知 元素表示可以通过TargetName设置Setter来访问它。我认为唯一适合的属性是Tag属性。然后,您可以使用Setter来设置已知元素的Tag属性。以下是遵循该想法的代码:

<ControlTemplate x:Key="Button">
        <Grid x:Name="button">                
            <Rectangle x:Name="ButtonTheme" RadiusX="10" RadiusY="10" Stroke="Silver" StrokeThickness="3" Fill="{TemplateBinding Background}"></Rectangle>
            <Rectangle x:Name="HighLight" Opacity="1.0" Tag="1">
                <Rectangle.Resources>
                   <DiscreteObjectKeyFrame x:Key="proxy" Value="{Binding ElementName=HighLight}"/>
                </Rectangle.Resources>
                <Rectangle.Fill>
                    <RadialGradientBrush Center="0.5,0.8">
                        <GradientStop x:Name="Flower" Color="#AAFFFFFF" 
                                      Offset="{Binding Value.Tag, Source={StaticResource proxy}}" />
                        <GradientStop Color="#00FFFFFF" Offset="0" />
                    </RadialGradientBrush>
                </Rectangle.Fill>
            </Rectangle>
            <ContentControl HorizontalAlignment="Center"
                            VerticalAlignment="Center"
                            Content= "{TemplateBinding Property = ContentControl.Content}" />
             </Grid>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True">
                <Setter TargetName="HighLight" Property="Tag" Value="0" />
            </Trigger>
        </ControlTemplate.Triggers>
 </ControlTemplate>

请注意,我将Tag设置为0以进行测试(在鼠标结束之前和之后偏移量应该不同),您可以将其设置为您想要的任何颜色。

非hacky方式是使用VisualStateManager,您可以这样做:

<ControlTemplate x:Key="Button">
    <Grid x:Name="button">                
        <Rectangle x:Name="ButtonTheme" RadiusX="10" RadiusY="10" Stroke="Silver" StrokeThickness="3" Fill="{TemplateBinding Background}"></Rectangle>
        <Rectangle x:Name="HighLight" Opacity="1.0" Tag="1">               
            <Rectangle.Fill>
                <RadialGradientBrush Center="0.5,0.8">
                    <GradientStop x:Name="Flower" Color="#AAFFFFFF" 
                                  Offset="1" />
                    <GradientStop Color="#00FFFFFF" Offset="0" />
                </RadialGradientBrush>
            </Rectangle.Fill>
        </Rectangle>
        <ContentControl HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        Content= "{TemplateBinding Property = ContentControl.Content}" />
         <VisualStateManager.VisualStateGroups>
             <VisualStateGroup Name="CommonStates">
                <VisualState Name="Normal"/>
                <VisualState Name="MouseOver">
                   <Storyboard>
                     <DoubleAnimation Storyboard.TargetName="HighLight" Storyboard.TargetProperty="Fill.GradientStops[0].Offset" 
                    To="0" Duration="0"/>
                   </Storyboard>
                </VisualState>
             </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
    </Grid>        
</ControlTemplate>

您使用DoubleAnimation中定位Fill.GradientStops[0].Offset的路径HighLight,因此了解要在鼠标悬停时更改其偏移量的GradientStop的索引非常重要。