2010-03-29 2 views
1

J'essaie d'animer un RadialGradientBrush dans mon application. Je reçois l'exception super utile:Problème lors de l'animation de RadialGradientBrush dans WPF

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.

Je sais qu'il est quelque chose de mal avec la propriété indirecte de ciblage ou qualification de chemin partiel dans l'attribut de mon DoubleAnimation de Storyboard.TargetProperty. Des idées?

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

Répondre

1

Le premier problème est que vous définissez l'arrière-plan à une brosse à gradient dans votre DataTrigger. Parce que cela sera appliqué plus tard, l'animation ne sera pas capable de trouver le pinceau (d'où l'erreur cryptique de ne pas trouver une propriété de dépendance). Donc la première chose que j'ai faite a été de définir l'arrière-plan de la bordure à la brosse manuellement, plutôt que dans le déclencheur.

Le deuxième problème était la façon dont vous définissiez la propriété cible. Vous n'avez pas besoin d'utiliser la syntaxe des parenthèses. Cela fonctionne très bien comme suit: Background.GradientStops[0].Offset.

Avec ces changements, la bordure s'anime parfaitement; voici la majoration finale:

<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

Pourquoi supprimer le GradientBrush du DataTrigger? L'OP peut exiger que le pinceau apparaisse UNIQUEMENT sur le déclencheur. – midspace

0

J'ai effectivement développé une solution au problème juste comme Charlie a posté son. On dirait que nous sommes arrivés à la même chose. Il suffit de poster le mien pour référence:

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

Ma réponse selon les commentaires dans l'exemple de code.

J'ai supprimé le MultiDataTrigger de mon premier message, car je n'arrive pas à le faire fonctionner avec des collections liées. Je pourrais avoir à demander cela pour voir si quelqu'un a une réponse à la question.

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

Lors d'un second examen du problème, je n'arrive pas à faire fonctionner le MultiDataTrigger comme il le devrait selon que l'élément lié est déjà visible ou non. L'un échouera avec l'exception et l'autre fonctionnera. Échanger les conditions autour de change comment cela fonctionne, retourne lequel échoue avec l'autre. Cela reste une réponse si elle est utilisée avec un seul DataTrigger. – midspace

+0

J'ai proposé la question en la faisant fonctionner avec MvvM. http://stackoverflow.com/questions/16181222/datatrigger-to-start-a-storyboard-within-an-itemscontrol-on-a-deep-binding-prope – midspace

Questions connexes