2010-04-29 58 views
4

我正在嘗試基於ViewModel中的屬性更改創建一個簡單的(我認爲)動畫效果。我希望目標是自定義控件的控件模板中的特定文本塊,該控件從Window繼承。WPF:選擇動畫的目標

從我看過的文章示例中,DataTrigger是實現此目的的最簡單方法。看起來,Window.Triggers不支持DataTriggers,這導致我嘗試在樣式中應用觸發器。我目前遇到的問題是我似乎無法定位TextBlock(或任何其他子控件) - 下面的代碼是將動畫應用於整個窗口的背景。

如果我完全離開StoryBoard.Target,效果完全一樣。

這是錯誤語法的正確方法,還是有更簡單的方法來實現這一點?

<Style x:Key="MyWindowStyle" TargetType="{x:Type Window}"> 
    <Setter Property="Template" Value="{StaticResource MyWindowTemplate}"/> 
    <Style.Triggers> 
     <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> 
      <DataTrigger.EnterActions> 
       <BeginStoryboard> 
        <Storyboard BeginTime="00:00:00" Duration="0:0:2" Storyboard.Target="{Binding RelativeSource={RelativeSource AncestorType=TextBlock}}" 
            Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
         <ColorAnimation FillBehavior="Stop" From="Black" To="Red" Duration="0:0:0.5" AutoReverse="True"/> 
        </Storyboard> 
       </BeginStoryboard> 
      </DataTrigger.EnterActions> 
     </DataTrigger> 
    </Style.Triggers> 
</Style> 

更新

應該也提到,我試圖命名的TextBlock,並通過StoryBoard.TargetName(如Timores建議)引用它,並得到了錯誤「的TargetName屬性不能在一組風格二傳手「。

+0

你想要的動畫目標究竟是什麼?你說*「自定義控件的控件模板中的特定文本塊」*,但是爲'Window'創建樣式而不是自定義控件。你能提供包含動畫目標的代碼嗎?上面的目標綁定不應該工作,因爲我不指望Window有一個TextBlock類型的祖先,是嗎?!這可能嗎? – gehho 2010-04-30 07:01:54

+0

對不起,這是一個難以描述的設置。自定義控件*是一個窗口,因爲它從窗口派生。安裝程序/樣式是由其他人創建的,所以我試圖改進這個動畫。 Textblock是一個子控件 - 再次查看它,RelativeSource/AncestorType可能不是很接近,因爲我試圖定位一個孩子而不是父母? – 2010-04-30 13:39:14

回答

4

編輯:我有監督的事實,TextBlock您的自定義窗口/控件的ControlTemplate。我不認爲有可能從ControlTemplate的以外的StoryboardControlTemplate內控制。但是,您可以在您的自定義窗口中定義的屬性,你那麼數據綁定到你的ChangeOccurred屬性,然後觸發添加到您的ControlTemplate現在將獲得由定製控件的屬性觸發,而不是窗口的視圖模型的財產(當然,間接地是由ViewModel觸發,因爲ChangeOccurred綁定到自定義窗口的屬性,這反過來觸發動畫 - 呃,複雜的句子,希望你能理解)。這是一個選項嗎?你可以關注嗎? ;-)

也許一些代碼可以幫助:

public class MyCustomWindow : Window 
{ 
    public static readonly DependencyProperty ChangeOccurred2 = DependencyProperty.Register(...); 

    public bool ChangeOccurred2 { ... } 

    // ... 
} 

和一些XAML:

<local:MyCustomWindow ChangeOccurred2="{Binding ChangeOccurred}" ... > 
    <!-- Your content here... --> 
</local:MyCustomWindow> 

<!-- Somewhere else (whereever your ControlTemplate is defined) --> 
<ControlTemplate TargetType="{x:Type local:MyCustomWindow}"> 

    <!-- your template here --> 

    <ControlTemplate.Triggers> 
     <Trigger Property="ChangeOccurred2" Value="True"> 
      <Trigger.EnterActions> 
       <BeginStoryboard> 
        <Storyboard BeginTime="00:00:00" Duration="0:0:2" 
           Storyboard.TargetName="txtWhatever" 
           Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
         <ColorAnimation FillBehavior="Stop" 
             From="Black" To="Red" 
             Duration="0:0:0.5" 
             AutoReverse="True"/> 
        </Storyboard> 
       </BeginStoryboard> 
      </Trigger.EnterActions> 
     </Trigger> 
    </ControlTemplate.Triggers> 
</ControlTemplate> 

注:我命名爲窗口的屬性ChangeOccurred2,因爲我想它是從視圖模型的區分ChangeOccurred財產。當然,你應該爲這個屬性選擇一個更好的名字。但是,我錯過了這樣一個決定的背景。


我以前的答案:

所以,要動畫一個TextBlock這在(自定義)窗口的內容?

爲什麼要在窗口上設置樣式,而不是在TextBlock本身上?也許你應該嘗試這樣(沒有測試這個!):

<local:MyCustomWindow ... > 
    <!-- ... --> 
    <TextBlock x:Name="textBlockAnimated" ... > 
     <TextBlock.Style> 
      <Style TargetType="{x:Type TextBlock}"> 
       <Style.Triggers> 
        <DataTrigger Binding="{Binding ChangeOccurred}" Value="True"> 
         <DataTrigger.EnterActions> 
          <BeginStoryboard> 
           <Storyboard BeginTime="00:00:00" Duration="0:0:2" 
              Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)"> 
            <ColorAnimation FillBehavior="Stop" 
                From="Black" To="Red" 
                Duration="0:0:0.5" 
                AutoReverse="True"/> 
           </Storyboard> 
          </BeginStoryboard> 
         </DataTrigger.EnterActions> 
        </DataTrigger> 
       </Style.Triggers> 
      </Style> 
     </TextBlock.Style> 
    </TextBlock> 
    <!-- ... --> 
</local:MyCustomWindow> 

{Binding ChangeOccurred}可能是不夠的。您可能需要將DataContext添加到TextBlock,或者添加RelativeSource或其他東西。

+0

您的更新答案有效!謝謝你的幫助。我覺得我接近它的方式倒退了,但我對WPF的造型/動畫非常新穎。 – 2010-04-30 15:49:36

0

MyWindowTemplate中的TextBlock?

如果是這樣,給TextBlock一個名稱並使用Storyboard.TargetName來引用它。

another question in SO

+0

對不起,應該提到我試過並得到了:「TargetName屬性不能在Style Setter上設置。」 – 2010-04-29 20:38:40

+0

另外:是的,它在控制模板中。 – 2010-04-29 20:42:06