2017-11-18 6 views
0

Ich versuche zu schreiben buttonStil, die innerhalb seiner eigenen Ressource Wörterbuch existiert. Es sollte eine Grundanimation haben, in der der Hintergrund der Schaltfläche von Dunkelgrau zu Hellgrau wechselt, wenn die Maus darüber bewegt wird.WPF: Vordefinierte Farbe in Storyboard-Animation, für eine Schaltfläche Stil innerhalb Ressource Wörterbuch

Das Problem ist, dass es die Tatsache nicht zu mögen scheint, dass ich durch Schlüssel AUSDRüCKLICH im Storyboard eine vordefinierte Farbe bin Referenzierung. Ich kann nicht verstehen, warum das so ist, weil ich es gewohnt bin, auf vorhandene Ressourcen zu verweisen.

Eine Ausnahme wird zur Laufzeit erhöht:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
       xmlns:local="clr-namespace:Style.Components.Buttons"> 


<Style TargetType="{x:Type Button}" x:Key="LargeFlatListOptionButtonStyle"> 
    <Setter Property="Foreground" Value="{DynamicResource TextParagraphWhiteP1}" /> 
    <Setter Property="BorderThickness" Value="0" /> 
    <Setter Property="Background" Value="{DynamicResource BackgroundGreyLevel2}" /> 
    <Setter Property="MinHeight" Value="32" /> 
    <Setter Property="MinWidth" Value="50" /> 
    <Setter Property="Padding" Value="6,2" /> 
    <Setter Property="BorderBrush" Value="{DynamicResource ControlOutlineUnselected}" /> 
    <Setter Property="SnapsToDevicePixels" Value="true" /> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="{x:Type Button}"> 
       <Grid> 
        <Border Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> 
         <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" /> 
        </Border> 
       </Grid> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
    <Style.Triggers> 
     <!-- ANIMATIONS --> 
     <EventTrigger RoutedEvent="Button.MouseEnter"> 
      <EventTrigger.Actions> 
       <BeginStoryboard> 
        <Storyboard> 
         <ColorAnimation To="{DynamicResource BackgroundGreyLevel2Color}" Storyboard.TargetProperty="(Border.BorderBrush).Color" Duration="0:0:0.1"/> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger.Actions> 
     </EventTrigger> 
    </Style.Triggers> 
</Style> 

Die Farb Ressource definiert ist hier:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
... 
<SolidColorBrush x:Key="BackgroundGreyLevel2" Color="#FF464646" /> 
<SolidColorBrush x:Key="TextParagraphWhiteP1" Color="White" /> 
<Color x:Key="BackgroundGreyLevel2Color" >#FF464646</Color> 
... 

</ResourceDictionary> 

"InvalidOperationException: Cannot freeze this Storyboard timeline tree for use across threads" 

Unterhalb der unvollendeten Stil für die Schaltfläche ist

Natürlich kann ich einfach die Farbe schreiben, die ich inline einblenden möchte, aber ich würde viel lieber die Ressource verwenden, die ich bereits definiert habe, als ob unser Stil von grau auf z. Blau; Ich würde daran denken müssen, es hier und an allen anderen Inline-Standorten zu ändern.

Antwort

1

Ein Zitat von Microsoft Docs on Storyboards.

Sie können keine dynamischen Ressourcenreferenzen oder Datenbindungsausdrücke verwenden, um Storyboard- oder Animationseigenschaftswerte festzulegen. Das liegt daran, dass alles innerhalb eines Styles Thread-sicher sein muss und das Timing-System Storyboard-Objekte einfrieren muss, um sie threadsicher zu machen. Ein Storyboard kann nicht eingefroren werden, wenn es oder seine untergeordneten Zeitleisten dynamische Ressourcenreferenzen oder Datenbindungsausdrücke enthalten.

Ich kann einige Abhilfen vorschlagen (was ich getan habe gesehen), die für Sie kann oder auch nicht:

  • Mit StaticResource Markup Erweiterung der Farb Ressource verweisen (es wird, wenn Sie arbeiten Definieren Sie die Farbressource neu, aber Benutzer Ihrer Bibliothek können sie später nicht mehr neu definieren). Dann könnte man einen "Basisstil" für Buttons haben und spezifische Styles für verschiedene farbige Buttons erstellen (Sie basieren auf diesem "Basisstil" und fügen Animationen unter Verwendung von StaticResource hinzu).
  • Ändern Sie die ControlTemplate, so dass Sie zwei verschiedenfarbige Oberflächen übereinander haben (sagen Sie, Sie haben einen Rahmen mit hellgrauem Hintergrund oben auf einem Rahmen mit dunkelgrauem Hintergrund) und animieren Sie dann die Opacity des oberen Elements. Sie verblassen grundsätzlich das oberste Element. Diese Elemente können DynamicResource verwenden, um ihre Eigenschaften festzulegen.
+0

djomlastic, danke für Ihre hilfreiche Antwort. Darf ich fragen, was Sie in Ihrem ersten Vorschlag meinen, indem Sie die Farbressource neu definieren? –

+0

@BenHayward Nun, wenn Sie BackgroundGreyLevel2Color ändern, um eine andere Farbe zu sein (sagen Sie rot), aber Sie den Schlüssel nicht ändern, wird Ihre Schaltfläche zu rot animiert. Das Problem von StaticResource vs DynamicResource bleibt bestehen. Wenn also ein Benutzer Ihrer Bibliothek entscheidet, dass BackgroundGreyLevel2Color golden (und nicht grau) sein soll, wird die Schaltfläche grau animiert.Ich glaube, dass die zweite Option besser sein könnte, das habe ich in Kontrollbibliotheken gesehen. – djomlastic

+0

@djomalstic Ich sehe - ich habe versucht, einfach das Storyboard in To = "{StaticResource BackgroundGreyLevel2Color}" zu ändern, aber das hat auch nicht funktioniert. Ich sehe, was du mit deinem zweiten Vorschlag meinst - das könnte die beste Lösung sein. Ich werde es versuchen! Vielen Dank –

Verwandte Themen