2009-08-06 37 views
7

我有最難的時候弄明白這一點:說我有兩個Button和三個TextBlocks。我想要任一按鈕在所有TextBlocks上觸發一個簡單的Storyboard。目前我試圖定義一個包含Storyboard的通用文本塊樣式,然後觸發器來自任何Button單擊。這是我來最接近的,但在啓動應用程序崩潰...我是什麼做的不是這裏出錯:WPF - 它要比我做得更容易

<Window.Resources> 

<Style TargetType="TextBlock" > 
    <Setter Property="Foreground" Value="Blue" /> 
    <Style.Resources> 
     <Storyboard x:Key="TextBlockOpacity" Storyboard.TargetProperty="Opacity"> 
      <DoubleAnimation From="0" To="1" /> 
     </Storyboard> 
    </Style.Resources>  
</Style> 

<Window.Triggers> 
    <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button"> 
     <BeginStoryboard Storyboard="{StaticResource TextBlockOpacity}"/> 
    </EventTrigger> 
</Window.Triggers> 


<Grid x:Name="LayoutRoot"> 
    <Button x:Name="button" HorizontalAlignment="Left" Margin="51,54,0,0" VerticalAlignment="Top" Width="96" Height="45" Content="Button"/> 

    <TextBlock x:Name="textBlock1" Margin="228,54,172,0" VerticalAlignment="Top" Height="45" FontSize="26.667" Text="TextBlock" TextWrapping="Wrap" /> 
    <TextBlock x:Name="textBlock2" Margin="228,103,172,0" VerticalAlignment="Top" Height="45" FontSize="26.667" Text="Hello" TextWrapping="Wrap"/> 
</Grid> 
+3

我覺得你的痛苦 – 2009-08-06 12:24:52

+0

你能嘗試給故事板的名稱,然後看是否在後臺代碼就可以正常開始()。它? – 2009-08-06 13:36:36

+0

你在這裏問同樣的問題:http://stackoverflow.com/questions/1238817/wpf-animation-question或者你正在尋找一個2按鈕點擊觸發器? – SergioL 2009-08-06 14:30:04

回答

4

基於kek444的Xaml-only解決方案,我提出了一個稍微改進的版本,它不依賴於按鈕的DataContext並且可以有多個觸發器。

<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    x:Class="WpfApplication1.MainWindow" 
    x:Name="Window" 
    Title="MainWindow" 
    Width="640" Height="480"> 
    <Window.Resources> 
     <UIElement x:Key="OpacityCounter" Opacity="0"/> 
     <Style TargetType="TextBlock"> 
      <Setter Property="Opacity" Value="{Binding Source={StaticResource OpacityCounter}, Path=Opacity}" /> 
     </Style> 
     <Storyboard x:Key="OnClick1"> 
      <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.Target="{StaticResource OpacityCounter}" Storyboard.TargetProperty="(UIElement.Opacity)"> 
       <SplineDoubleKeyFrame KeyTime="00:00:00" Value="0"/> 
       <SplineDoubleKeyFrame KeyTime="00:00:00.5000000" Value="1"/> 
      </DoubleAnimationUsingKeyFrames> 
     </Storyboard> 
    </Window.Resources> 
    <Window.Triggers> 
     <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button1"> 
      <BeginStoryboard Storyboard="{StaticResource OnClick1}"/> 
     </EventTrigger> 
     <EventTrigger RoutedEvent="ButtonBase.Click" SourceName="button2"> 
      <BeginStoryboard Storyboard="{StaticResource OnClick1}"/> 
     </EventTrigger> 
    </Window.Triggers> 

    <Grid x:Name="LayoutRoot"> 
     <StackPanel> 
      <StackPanel Orientation="Horizontal"> 
       <Button x:Name="button1" Width="131" Height="37" Content="Button 1" Margin="0,0,0,22"/> 
       <Button x:Name="button2" Width="131" Height="37" Content="Button 2" Margin="0,0,0,22"/> 
      </StackPanel> 
      <TextBlock x:Name="textBlock" Height="27" Text="TextBlock 1" TextWrapping="Wrap" /> 
      <TextBlock x:Name="textBlock1" Height="27" Text="TextBlock 2" TextWrapping="Wrap" /> 
      <TextBlock x:Name="textBlock2" Height="27" Text="TextBlock 3" TextWrapping="Wrap" /> 
      <TextBlock x:Name="textBlock3" Height="27" Text="TextBlock 4" TextWrapping="Wrap" /> 
     </StackPanel> 
    </Grid> 
</Window> 

了使用列表框作爲一種觸發機制(前提是你有一個名爲「ListBox1的」在某處列表框,添加以下Window.Triggers:

<EventTrigger RoutedEvent="Selector.SelectionChanged" SourceName="listbox1"> 
    <BeginStoryboard Storyboard="{StaticResource OnClick1}"/> 
</EventTrigger> 

或觸發關閉特定ListBoxItem的,你需要(其中物品1被命名ListBoxItem的):

<EventTrigger RoutedEvent="ListBoxItem.Selected" SourceName="item1"> 
    <BeginStoryboard Storyboard="{StaticResource OnClick1}"/> 
</EventTrigger> 
+0

非常好!我想避免創建UIElements作爲資源,但人們應該更適合他們。然而,調用這種方法的基礎是它沒有使用DataContext並支持多個觸發器會有些不公平。使用DataContext上的資源UIElement只是個人偏好的問題;並且這兩種解決方案都支持多個觸發器。否則,工作很好。 ;) – 2009-08-06 15:22:12

+0

好吧......現在讓它稍微複雜一點......我並不是真的試圖觸發一個按鈕,而是從一個ListPanel的一個ListBox裏面的一個StackPanel內部,一個Border內部主窗口中的網格。我一直在嘗試這個小時,但不能得到正確的RoutedEvent ...所有的ListBoxItem事件給出了關於類被密封或錯誤的錯誤... – LSTayon 2009-08-06 15:28:49

+0

我只稱它改進了,因爲它不需要單獨的DataContext每個觸發機制(即按鈕)。我並不是故意要冒犯。 – SergioL 2009-08-06 15:36:26

6

如果「奉獻」按鈕改變不透明度,您可以利用其DataContext併爲其設置動畫。然後,只需綁定你的元素OpacityDataContext

(我也重構XAML中位)

<Window x:Class="SomeNamespace.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:System="clr-namespace:System;assembly=mscorlib" 
    Title="Window1" Height="300" Width="300"> 
    <Window.Resources>   
     <Storyboard x:Key="TextBlockOpacity" Storyboard.TargetName="button1" Storyboard.TargetProperty="DataContext" > 
      <DoubleAnimation From="0.1" To="1"/> 
     </Storyboard>   
     <Style TargetType="TextBlock" > 
      <Setter Property="Foreground" Value="Blue" /> 
      <Setter Property="Background" Value="LightGray" /> 
      <Setter Property="FontSize" Value="26.667" /> 
      <Setter Property="TextWrapping" Value="Wrap" /> 
      <Setter Property="Height" Value="45" />    
      <Setter Property="Opacity" Value="{Binding ElementName=button1, Path=DataContext}"/> 
     </Style> 
    </Window.Resources> 

    <Window.Triggers> 
     <EventTrigger RoutedEvent="ButtonBase.Click"> 
      <BeginStoryboard Storyboard="{StaticResource TextBlockOpacity}" > 
      </BeginStoryboard> 
     </EventTrigger> 

     <EventTrigger RoutedEvent="ListBox.SelectionChanged"> 
      <BeginStoryboard Storyboard="{StaticResource TextBlockOpacity}" > 
      </BeginStoryboard> 
     </EventTrigger> 
    </Window.Triggers> 

    <Grid x:Name="LayoutRoot"> 
     <Button x:Name="button1" HorizontalAlignment="Left" Margin="51,54,0,0" VerticalAlignment="Top" Width="96" Height="45" Content="Button"> 
      <Button.DataContext> 
       <System:Double>0</System:Double> 
      </Button.DataContext> 
     </Button> 

     <Button x:Name="button2" HorizontalAlignment="Right" Margin="0,54,29,0" VerticalAlignment="Top" Width="96" Height="45" Content="Button"/> 

     <ListBox x:Name="listBox1" Height="50" VerticalAlignment="Top"> 
      <ListBox.Items> 
       <System:String>Text1</System:String> 
       <System:String>Text2</System:String> 
      </ListBox.Items> 
     </ListBox> 

     <TextBlock x:Name="textBlock1" Margin="51,114,61,0" Text="TextBlock" Height="45" VerticalAlignment="Top" Width="166" /> 
     <TextBlock x:Name="textBlock2" Margin="51,0,74,42" Text="Hello" Height="45" Width="153" VerticalAlignment="Bottom" /> 
    </Grid> 
</Window> 

還要注意一兩件事 - 這就是,如果你想你儘量減少使用的方法代碼,使這一切都發生在xaml中。你的方法將整個窗口的Opacity。這就是爲什麼在上面的代碼中,TextBlocks綁定到按鈕的本身爲動畫的DataContext

它當然可以不綁定到公共值(DataContext),但是您需要重複X動畫(因爲您需要設置X TargetNames)。上述方法更容易擴展和維護。

編輯

增加了一個按鈕和各種:)

0

在你的樣品,要定義的故事板樣式的資源裏面,但你正在試圖訪問它作爲一個列表框一個Window資源。嘗試將Storyboard聲明移至Window.Resources,然後在Style中引用Storyboard。

我不知道它是否會做你想做的事,但我會從那裏開始。

+0

好吧,我一直在這裏一直運行着,但是它歸結到的是NameScope。我有一個ListBox,我想觸發TextBlocks上的Animation,但它們不在同一個NameScope中,所以如果我將StoryBoard放入Windows.Resources中,那麼ListBox觸發器可以找到StoryBoard,但StoryBoard找不到TextBlocks的TargetName。 如果我把StoryBoard放在Grid.Resource(TextBlocks所在的位置),那麼ListBox更改觸發器無法找到StoryBoard。是否有一些命名約定可以用來跨越Namescopes? 呃!謝謝! – LSTayon 2009-08-06 15:50:35

相關問題