Проблемы с анимацией RadialGradientBrush в WPF - PullRequest
1 голос
/ 29 марта 2010

Я пытаюсь анимировать RadialGradientBrush в моем приложении. Я получаю супер полезное исключение:

Additional information: 'System.Windows.Style' value cannot be assigned to property 'Style' of object 'System.Windows.Controls.Border'. '[Unknown]' property does not point to a DependencyObject in path '(0).(1).[0].(2)'. Error at object 'System.Windows.Style' in markup file 'Eng.Modules.Core;component/system/grid/systemgridview.xaml' Line 252 Position 51.

Я знаю, что что-то не так с косвенным таргетингом свойства или частичным определением пути в моем атрибуте DoubleAnimation Storyboard.TargetProperty. Есть идеи?

<Border>
  <Border.Resources>
    <RadialGradientBrush x:Key="SomeBrush">
      <RadialGradientBrush.GradientStops>
        <GradientStop Color="White" Offset="0" />
        <GradientStop Color="Gold" Offset="1" />
      </RadialGradientBrush.GradientStops>
    </RadialGradientBrush>
  </Border.Resources>
  <Border.Style>
    <Style TargetType="{x:Type Border}">
      <Style.Triggers>
        <DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}}" Value="True">
          <Setter Property="Background" Value="{StaticResource SomeBrush}" />
          <DataTrigger.EnterActions>
            <BeginStoryboard x:Name="SomeStoryBoard">
              <Storyboard>
                <!-- RIGHT HERE -->
                <DoubleAnimation
                  Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].(GradientStop.Offset)"
                  From="0" To="1" Duration="0:0:1"
                  RepeatBehavior="Forever"
                  AutoReverse="True" />
              </Storyboard>
            </BeginStoryboard>
          </DataTrigger.EnterActions>
          <DataTrigger.ExitActions>
            <RemoveStoryboard BeginStoryboardName="SomeStoryBoard" />
          </DataTrigger.ExitActions>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Border.Style>
</Border>

Ответы [ 3 ]

1 голос
/ 17 апреля 2013

Мой ответ согласно комментариям в примере кода.

Я удалил MultiDataTrigger из моего первого поста, так как я не могу заставить себя работать со связанными коллекциями. Возможно, мне придется спросить об этом, чтобы узнать, есть ли у кого-нибудь ответ на вопрос.

<Grid>
    <Grid.Resources>
            <!-- Don't use a ControlTemplate. This destroys your control structure, 
which doesn't make sense if all you want to do is animate the background. -->
            <Style x:Key="MyAnimatedFeatureStyle" TargetType="Button">
                <Style.Resources>
                    <RadialGradientBrush x:Key="GoldRadialGradientBrush">
                    <RadialGradientBrush.GradientStops>
                        <GradientStop Color="White" Offset="0" />
                        <GradientStop Color="Gold" Offset="1" />
                    </RadialGradientBrush.GradientStops>
                </RadialGradientBrush>
                <Storyboard RepeatBehavior="Forever" AutoReverse="False" x:Key="SomeStoryBoard">
                    <DoubleAnimation Storyboard.TargetProperty="Background.GradientStops[0].Offset" From="0" To="1" Duration="0:0:1" RepeatBehavior="Forever" AutoReverse="True" />
                </Storyboard>
            </Style.Resources>
            <Style.Triggers>
                <!-- Your primary binding condition. Whatever this may be. -->
                <DataTrigger Binding="{Binding Path=IsSOMTHINGSET}" Value="true" >
                    <!-- The Background is here in the setter, because we only want the background colored and animated on the binding condition. -->
                    <Setter Property="Background" Value="{StaticResource GoldRadialGradientBrush}" />
                    <DataTrigger.EnterActions>
                        <BeginStoryboard x:Name="BorderStoryBoard" Storyboard="{StaticResource SomeStoryBoard}" />
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <RemoveStoryboard BeginStoryboardName="BorderStoryBoard" />
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Grid.Resources>

    <Button Style="{StaticResource MyAnimatedFeatureStyle}" />
</Grid>
1 голос
/ 29 марта 2010

Первая проблема заключается в том, что вы устанавливаете фон для градиентной кисти в DataTrigger. Поскольку это применяется позже, анимация не сможет найти кисть (отсюда загадочная ошибка, связанная с отсутствием свойства зависимости). Поэтому первое, что я сделал, - установил фон границы для кисти вручную, а не в триггере.

Вторая проблема заключалась в том, как вы настраивали целевое свойство. Вам не нужно использовать синтаксис в скобках - он отлично работает следующим образом: Background.GradientStops[0].Offset.

С этими изменениями граница оживляет идеально; вот последняя наценка:

<Border>
    <Border.Background>
        <RadialGradientBrush>
            <RadialGradientBrush.GradientStops>
                <GradientStop Color="White" Offset="0" />
                <GradientStop Color="Gold" Offset="1" />
            </RadialGradientBrush.GradientStops>
        </RadialGradientBrush>
    </Border.Background>
    <Border.Style>
        <Style TargetType="{x:Type Border}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}}" Value="True">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard x:Name="SomeStoryBoard">
                            <Storyboard>
                                <!-- RIGHT HERE -->
                                <DoubleAnimation 
                                      Storyboard.TargetProperty="Background.GradientStops[0].Offset"
                                      From="0" To="1" Duration="0:0:1"
                                      RepeatBehavior="Forever"
                                      AutoReverse="True" />
                            </Storyboard>
                        </BeginStoryboard>
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <RemoveStoryboard BeginStoryboardName="SomeStoryBoard" />
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Border.Style>
</Border>
0 голосов
/ 29 марта 2010

Я действительно разработал решение проблемы, как раз когда Чарли опубликовал его. Похоже, мы придумали почти одно и то же. Просто опубликовать мой для справки:

<Button>
  <Button.Style>
    <Style TargetType="{x:Type Button}">
      <Setter Property="Template">
        <Setter.Value>
          <ControlTemplate>
            <ControlTemplate.Resources>
              <RadialGradientBrush x:Key="GoldRadialGradientBrush">
                <RadialGradientBrush.GradientStops>
                  <GradientStop Color="White" Offset="0" />
                  <GradientStop Color="Gold" Offset="1" />
                </RadialGradientBrush.GradientStops>
              </RadialGradientBrush>
              <Storyboard x:Key="SomeStoryBoard">
                <DoubleAnimation
                  Storyboard.TargetProperty="(Border.Background).(GradientBrush.GradientStops)[0].Offset"
                  From="0" To="1" Duration="0:0:1"
                  RepeatBehavior="Forever"
                  AutoReverse="True" />
              </Storyboard>
            </ControlTemplate.Resources>
            <Grid>
              <Border Background="{StaticResource GoldRadialGradientBrush}">
                <Border.Style>
                  <Style TargetType="{x:Type Border}">
                    <Style.Triggers>
                      <DataTrigger Binding="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}}" Value="True">
                        <DataTrigger.EnterActions>
                          <BeginStoryboard x:Name="BorderStoryBoard" Storyboard="{StaticResource SomeStoryBoard}" />
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                          <RemoveStoryboard BeginStoryboardName="BorderStoryBoard" />
                        </DataTrigger.ExitActions>
                      </DataTrigger>
                    </Style.Triggers>
                  </Style>
                </Border.Style>
              </Border>
            </Grid>
          </ControlTemplate>
        </Setter.Value>
      </Setter>
    </Style>
  </Button.Style>
</Button>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...