WPF: кнопка ControlTemplate + пробел = исключение? - PullRequest
1 голос
/ 19 мая 2009

Я собрал шаблон в Expression Blend для кнопки, и он работает нормально - пока я не нажму на него и не нажму пробел. Я получаю следующую ошибку:

InvalidOperationException Свойство [Unknown] 'не указывает на объект DependencyObject в пути' (0). (1). [0]. (2) '.

Код выглядит следующим образом:

    <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>

Может показаться, что либо MouseOverStoryboard, либо UnMouseOverStoryboard запускаются (путь, указанный в ошибке, похоже, соответствует TargetProperty). Я не уверен, почему любой из них будет срабатывать при нажатии пробела, хотя ... Есть предложения?

EDIT: Благодаря Райану Версоу я попробовал следующее, которое теперь не позволяет щелкнуть по пробелу и выдает исключение:

            <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>

Теперь тип кисти остается согласованным (LinearGradientBrush), и всегда доступен 0-й GradientStop.

Мне по-прежнему любопытно еще одно - как лучше всего это сделать 1016 *, учитывая, что эта разновидность воспринимается как хак (например, добавлен / анимирован третий градиентный останов, затем третий GradientStop должен быть добавлен, когда IsPressed == True).

Спасибо за предложения! Надеюсь, это поможет кому-то еще.

Ответы [ 3 ]

1 голос
/ 19 мая 2009

Похоже, что Setter вашего IsPressed Trigger пытается присвоить значение цвета (# FF92A2D3) свойству Background вашей границы. Однако свойство Background вашей границы содержит линейную градиентную кисть, а не однотонную кисть. Впрочем, это только на первый взгляд.

1 голос
/ 19 мая 2009

Я не уверен, какое было бы оптимальное решение, но я нашел то, которое работает.

Создайте LinearGradientBrush в своих ресурсах:

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

Измените триггер IsPressed на следующее (только изменения Value):

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

Это должно заменить весь фон на новый (который также является LinearGradientBrush).

1 голос
/ 19 мая 2009

Если вы нажмете пробел, это все равно что нажать кнопку.
Вы должны посмотреть на IsPressed триггер

...