views:

752

answers:

3

Hello,

I've thrown together a template in Expression Blend for a button, and it works alright - until I tab over to it and press the spacebar. I get the following error:

InvalidOperationException '[Unknown]' property does not point to a DependencyObject in path '(0).(1).[0].(2)'.

The code is as follows:

    <ControlTemplate x:Key="EmailButton" TargetType="{x:Type Button}">
        <ControlTemplate.Resources>
         <Storyboard x:Key="MouseOverStoryboard">
          <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="border" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
           <SplineColorKeyFrame KeyTime="00:00:00.4000000" Value="#FF55679E"/>
          </ColorAnimationUsingKeyFrames>
         </Storyboard>
         <Storyboard x:Key="UnMouseOverStoryboard">
          <ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="border" Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[0].(GradientStop.Color)">
           <SplineColorKeyFrame KeyTime="00:00:00.4000000" Value="#FF92A2D3"/>
          </ColorAnimationUsingKeyFrames>
         </Storyboard>
        </ControlTemplate.Resources>
        <Border x:Name="border" BorderBrush="#FF000000" BorderThickness="2,2,2,2" CornerRadius="4,4,4,4">
         <Border.Background>
          <LinearGradientBrush EndPoint="0.47,-0.01" StartPoint="0.47,0.808">
           <GradientStop Color="#FF92A2D3" Offset="0"/>
           <GradientStop Color="#FFFFFFFF" Offset="1"/>
          </LinearGradientBrush>
         </Border.Background>
         <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}"/>
        </Border>
        <ControlTemplate.Triggers>
         <Trigger Property="IsPressed" Value="True">
          <Setter Property="Background" TargetName="border" Value="#FF92A2D3"/>
         </Trigger>
         <Trigger Property="IsMouseOver" Value="True">
          <Trigger.EnterActions>
           <BeginStoryboard x:Name="MouseOverStoryboard_BeginStoryboard" Storyboard="{StaticResource MouseOverStoryboard}"/>
          </Trigger.EnterActions>
          <Trigger.ExitActions>
           <BeginStoryboard x:Name="UnMouseOverStoryboard_BeginStoryboard" Storyboard="{StaticResource UnMouseOverStoryboard}"/>
          </Trigger.ExitActions>
         </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>

It would seem like either the MouseOverStoryboard or UnMouseOverStoryboard are being fired (The path mentioned in the error seems to match the TargetProperty). I'm not sure why either would fire when pressing the spacebar though... Any suggestions?

EDIT: Thanks to Ryan Versaw, I tried the following, which now prevents spacebar-clicking from throwing the exception:

         <Trigger Property="IsPressed" Value="True">
          <Setter Property="Background" TargetName="border">
           <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
             <GradientStop Color="#FF92A2D3" Offset="0"/>
             <GradientStop Color="#FF92A2D3" Offset="1"/>
            </LinearGradientBrush>
           </Setter.Value>
          </Setter>
         </Trigger>

Now the brush type stays consistent (LinearGradientBrush), and there is always 0th GradientStop available.

I'm still curious about one other thing - what is the best way to go about this, considering that this sorta feels like a hack (ex: a third gradient stop is added/animated, then a third GradientStop needs to be added when IsPressed==True).

Thanks for the suggestions! Hopefully this will help someone else, too.

+1  A: 

If you press the Spacebar is like clicking the button.
You should look at the IsPressed trigger

Eduardo Molteni
+1  A: 

It looks like your IsPressed Trigger's Setter is trying to assign a color value (#FF92A2D3) to the Background property of your border. However, the Background Property of your border contains a Linear Gradient Brush, not a Solid Color Brush. That's just a first glance opinion, though.

Pwninstein
+1  A: 

I'm not sure what the optimal solution would be, but I found one that works.

Create a LinearGradientBrush in your resources:

<LinearGradientBrush x:Key="solidBrush">
    <GradientStop Color="#FF92A2D3"/>
</LinearGradientBrush>

Change your IsPressed trigger to the following (only the Value changes):

<Trigger Property="IsPressed" Value="True">
    <Setter Property="Background" TargetName="border" Value="{StaticResource solidBrush}"/>
</Trigger>

This should swap out your entire background for a new one (which is also a LinearGradientBrush).

Ryan Versaw
To give credit where it's due, I tried swapping the background out with a similar Brush due to Pwninstein's answer. Other ways may work, but this worked for me.
Ryan Versaw