2013-07-29 37 views
5

Tôi đang cố gắng tạo một bảng phân cảnh trong XAML làm hoạt hình một thuộc tính của một trong các phần tử con của phần tử làm tăng sự kiện. Nhưng tôi dường như không thể làm cho nó hoạt động mà không sử dụng Tên, đó là điều tôi không thể thực hiện trong tình huống cụ thể này.WPF Animate tài sản của trẻ em mà không cần sử dụng Tên

tôi về cơ bản đang cố gắng một cái gì đó như thế này (nhiều đơn giản hóa tất nhiên):

<Canvas> 
     <Canvas.Triggers> 
     <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
      <EventTrigger.Actions> 
       <BeginStoryboard> 
        <Storyboard> 
        <DoubleAnimation Storyboard.TargetProperty="Children[0].(Canvas.Left)" From="0" To="400" /> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger.Actions> 
     </EventTrigger> 
     </Canvas.Triggers> 

     <Button Canvas.Left="20" Canvas.Top="20">A</Button> 
     <Button Canvas.Left="40" Canvas.Top="20">B</Button> 
    </Canvas> 

Bất kỳ ý tưởng về cách thức này có thể đạt được?

Trả lời

5

Cung cấp rằng UIElement bạn đang lập chỉ mục trong phim hoạt hình tồn tại (tức là đã hiện diện trên Canvas) sau đó bạn có thể làm như sau:

<Canvas x:Name="MyCanvas"> 
    <Button x:Name="btn" Canvas.Left="20" Canvas.Top="20">A</Button> 
    <Button Canvas.Left="40" Canvas.Top="20">B</Button> 
    <Canvas.Triggers> 
     <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
      <EventTrigger.Actions> 
       <BeginStoryboard> 
        <Storyboard> 
         <DoubleAnimation Storyboard.Target="{Binding ElementName=MyCanvas, Path=Children[0]}" 
             Storyboard.TargetProperty="(Canvas.Left)" From="0" To="400" /> 
        </Storyboard> 
       </BeginStoryboard> 
      </EventTrigger.Actions> 
     </EventTrigger> 
    </Canvas.Triggers> 
</Canvas> 

Chú ý làm thế nào tôi đã chuyển việc bổ sung các nút bên trên Trigger . Nếu các Nút nằm bên dưới số Trigger như trong câu hỏi của bạn, hãy thử truy cập Children[0] sẽ ném một số ArgumentOutOfRangeException vì không có trẻ em vào thời điểm này.

+1

Có! Bạn đã thắng, +1 =). –

1

Để sử dụng Storyboard.TargetProperty trong hoạt ảnh, nó phải luôn là thuộc tính phụ thuộc. Children thuộc tính nhận được UIElementCollection yếu tố con của Panel (Canvas) này. Do đó, việc xây dựng sau đây Children [n] trả lại UIElement, sẽ dẫn đến một loại nhất định, để truy cập thuộc tính phụ thuộc của nó.

Điều này có thể được thực hiện trong các mã như sau:

Button MyButton = (Button)MyCanvas.Children[0]; 

MessageBox.Show(MyButton.Width.ToString()); 

Tất cả những hành động thiếu trong hoạt theo mặc định, đây là xây dựng của bạn sẽ không hoạt động.

Tôi đề xuất tạo hoạt ảnh trong mã nơi chuyển đổi này có thể.

Để chứng minh điều này, tôi đã tạo một Canvas, trong trường hợp Loaded có hoạt ảnh đã đăng ký. Số phần tử được đặt thông qua thuộc tính phụ thuộc đính kèm (tất nhiên, ví dụ có thể được triển khai theo nhiều cách khác nhau). Dưới đây là ví dụ của tôi:

XAML

<Grid> 
    <local:MyCanvas x:Name="MyCanvas" local:ClassForAnimation.Children="1"> 
     <Button Canvas.Left="20" Canvas.Top="20">A</Button> 
     <Button Canvas.Left="40" Canvas.Top="20">B</Button> 
    </local:MyCanvas> 
</Grid> 

Code behind

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
    }  
} 

public class MyCanvas : Canvas 
{ 
    public MyCanvas() 
    { 
     this.Loaded += new RoutedEventHandler(MyCanvas_Loaded); 
    } 

    private void MyCanvas_Loaded(object sender, RoutedEventArgs e) 
    { 
     MyCanvas myCanvas = sender as MyCanvas; 

     // Get No. of children 
     int children = ClassForAnimation.GetChildren(myCanvas); 

     // Get current Button for animation 
     Button MyButton = (Button)myCanvas.Children[children]; 

     if (myCanvas != null) 
     { 
      DoubleAnimation doubleAnimation = new DoubleAnimation(); 

      doubleAnimation.From = 0; 
      doubleAnimation.To = 400; 

      MyButton.BeginAnimation(Button.WidthProperty, doubleAnimation); 
     } 
    } 
} 

public class ClassForAnimation : DependencyObject 
{ 
    public static readonly DependencyProperty ChildrenProperty; 

    public static void SetChildren(DependencyObject DepObject, int value) 
    { 
     DepObject.SetValue(ChildrenProperty, value); 
    } 

    public static int GetChildren(DependencyObject DepObject) 
    { 
     return (int)DepObject.GetValue(ChildrenProperty); 
    } 

    static ClassForAnimation() 
    { 
     PropertyMetadata MyPropertyMetadata = new PropertyMetadata(0); 

     ChildrenProperty = DependencyProperty.RegisterAttached("Children", 
                  typeof(int), 
                  typeof(ClassForAnimation), 
                  MyPropertyMetadata); 
    }  
} 

Note: Tiếp cận các mục trong Canvas chỉ nên được thực hiện trong trường hợp Loaded, hoặc khi nó đã kết thúc. Nếu không, các mục không có sẵn vì chúng không được tải.

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