2009-08-06 23 views
7

Tôi đang có thời gian tối ưu tìm ra điều này: nói rằng tôi có hai Button và ba TextBlocks. Tôi muốn một trong hai nút để kích hoạt một Storyboard đơn giản trên tất cả TextBlocks. Hiện tại tôi đang cố gắng xác định một phong cách Textblock chung có chứa Storyboard, và sau đó kích hoạt xuất phát từ bất kỳ nút bấm nào. Đây là cảm giác mà tôi đã đến nhưng treo ứng dụng khi khởi động ... những gì là tôi làm không sai ở đây:WPF - nó phải dễ dàng hơn tôi đang làm cho nó

<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

tôi cảm thấy nỗi đau của bạn –

+0

bạn có thể thử cho Storyboard một tên, và sau đó nhìn thấy nếu trong code-behind bạn đúng cách có thể Begin()... nó? –

+0

Bạn có hỏi cùng một câu hỏi ở đây không: http://stackoverflow.com/questions/1238817/wpf-animation-question hoặc bạn đang tìm kiếm trình kích hoạt nhấp chuột vào nút 2? – SergioL

Trả lời

4

Dựa trên giải pháp Xaml-only của kek444, tôi trình bày một phiên bản được cải thiện một chút không dựa vào DataContext của nút và có thể có nhiều trình kích hoạt.

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

Để sử dụng một ListBox như một cơ chế kích hoạt (với điều kiện bạn có một ListBox tên là "ListBox1" một nơi nào đó, thêm dòng sau vào Window.Triggers:

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

hoặc để kích hoạt tắt một ListBoxItem cụ thể, bạn sẽ cần (nơi item1 là một tên ListBoxItem):

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

Khá đẹp! Tôi muốn tránh tạo ra UIElements làm tài nguyên, nhưng mọi người nên đi với những gì phù hợp với họ tốt hơn. Tuy nhiên, việc gọi phương pháp này được cải thiện dựa trên thực tế là nó không sử dụng DataContext và hỗ trợ nhiều trình kích hoạt sẽ có phần không công bằng. Sử dụng tài nguyên UIElement trên DataContext chỉ là vấn đề sở thích cá nhân; và cả hai giải pháp đều hỗ trợ nhiều trình kích hoạt tốt. Nếu không, công việc tốt đẹp. ;) –

+0

Ok ... bây giờ để làm cho nó hơi phức tạp hơn ... Tôi không thực sự cố gắng để kích hoạt tắt của một nút, nhưng tắt của một ListBoxItem thay đổi từ một ListBox đó là bên trong một StackPanel, bên trong một biên giới, bên trong một Grid trong cửa sổ chính. Tôi đã cố gắng này trong nhiều giờ nhưng không thể có được RoutedEvent đúng ... tất cả các sự kiện ListBoxItem cung cấp cho một lỗi về lớp đang được niêm phong hoặc một cái gì đó ... – LSTayon

+0

Tôi chỉ gọi nó được cải thiện vì nó không đòi hỏi một DataContext riêng biệt cho mỗi Cơ chế kích hoạt (tức là các nút). Tôi không có ý xúc phạm. – SergioL

6

Nếu bạn "dành" nút để thay đổi độ mờ đục, bạn có thể khai thác DataContext và tạo hiệu ứng động. Sau đó chỉ cần liên kết các yếu tố của bạn Opacity đến DataContext:

(Tôi cũng refactored XAML của bạn một chút)

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

Cũng lưu ý một điều - đây là cách tiếp cận để sử dụng nếu bạn muốn thu nhỏ của bạn mã, làm cho tất cả diễn ra trong xaml. Cách tiếp cận của bạn sẽ là anmate của Opacity của toàn bộ Cửa sổ. Đó là lý do tại sao trong đoạn mã trên, TextBlocks liên kết với nút của DataContext, đó là bản thân nó hoạt hình.

Tất nhiên là có thể thực hiện được mà không ràng buộc với giá trị chung (DataContext), nhưng sau đó bạn cần lặp lại hoạt ảnh X (vì bạn cần đặt X TargetNames). Cách tiếp cận này ở trên dễ dàng mở rộng và bảo trì hơn.

EDIT

gia tăng khác Button và một ListBox cho nhiều :)

0

Trong mẫu của bạn, bạn đang định Storyboard bên trong một phong cách như một tài nguyên, nhưng sau đó bạn đang cố gắng truy cập vào nó như tài nguyên Window. Hãy thử di chuyển khai báo Storyboard sang Window.Resources, sau đó tham khảo Storyboard trong Style.

Tôi không biết ngay nếu nó sẽ làm những gì bạn muốn, nhưng tôi sẽ bắt đầu ở đó.

+0

Được rồi, tôi đã chạy quanh đây mãi mãi, nhưng những gì nó sôi xuống là NameScope.Tôi có một ListBox mà tôi muốn kích hoạt Animation trên TextBlocks, nhưng chúng không nằm trong cùng NameScope, vì vậy nếu tôi đặt StoryBoard trong Windows.Resources, thì kích hoạt ListBox có thể tìm thấy StoryBoard nhưng StoryBoard không thể tìm thấy TargetName của TextBlocks. Nếu tôi đặt StoryBoard trong Grid.Resource (nơi TextBlocks là) thì trình kích hoạt thay đổi ListBox không thể tìm thấy StoryBoard. Có một số quy ước đặt tên tôi có thể sử dụng để vượt qua chữ cái? Ugh! Cảm ơn! – LSTayon

Các vấn đề liên quan