2012-06-12 34 views
5

Làm cách nào để tạo hiệu ứng cho chiều rộng của phần tử từ 0 đến chiều rộng thực tế của nó trong WPF?Chiều rộng hoạt ảnh với chiều rộng thực tế trong WPF?

Tôi cố gắng này:

<ControlTemplate.Triggers> 
    <EventTrigger RoutedEvent="Loaded"> 
     <BeginStoryboard> 
      <Storyboard> 
       <DoubleAnimation Duration="0:0:0.3" To="{Binding ElementName=MyElement, Path=ActualWidth}" From="0" Storyboard.TargetProperty="Width" Storyboard.TargetName="MyElement" /> 
      </Storyboard> 
     </BeginStoryboard> 
    </EventTrigger> 
</ControlTemplate.Triggers> 

Nếu tôi thay đổi liên kết với một giá trị cứng mã hoá, như 100, sau đó chiều rộng được hoạt hình đúng cách, ngoại trừ việc tôi muốn liên kết với độ rộng thực tế của nguyên tố này.

Nếu quan trọng, MyElement là đường viền và tôi đang tạo hoạt ảnh cho mục tab.

Đối với hồ sơ, điều này không làm việc, hoặc:

To="{Binding RelativeSource={RelativeSource AncestorType={x:Type Border}}, Path=ActualWidth}" 

Trả lời

9

Tôi chắc chắn điều này là sai vì nhiều lý do và xin vui lòng cho tôi biết có bao nhiêu luật WPF mà tôi đã vi phạm nhưng .. Tôi đã giải quyết vấn đề tương tự bằng cách tạo BindableDoubleAnimation của riêng tôi.

public class BindableDoubleAnimation : DoubleAnimationBase 
{ 
    DoubleAnimation internalAnimation; 

    public DoubleAnimation InternalAnimation { get { return internalAnimation; } } 

    public double To 
    { 
     get { return (double)GetValue(ToProperty); } 
     set { SetValue(ToProperty, value); } 
    } 

    /// <summary> 
    /// Dependency backing property for the <see cref="To"/> property. 
    /// </summary> 
    public static readonly DependencyProperty ToProperty = 
     DependencyProperty.Register("To", typeof(double), typeof(BindableDoubleAnimation), new UIPropertyMetadata(0d, new PropertyChangedCallback((s, e) => 
      { 
       BindableDoubleAnimation sender = (BindableDoubleAnimation)s; 
       sender.internalAnimation.To = (double)e.NewValue; 
      }))); 


    public double From 
    { 
     get { return (double)GetValue(FromProperty); } 
     set { SetValue(FromProperty, value); } 
    } 

    /// <summary> 
    /// Dependency backing property for the <see cref="From"/> property. 
    /// </summary> 
    public static readonly DependencyProperty FromProperty = 
     DependencyProperty.Register("From", typeof(double), typeof(BindableDoubleAnimation), new UIPropertyMetadata(0d, new PropertyChangedCallback((s, e) => 
     { 
      BindableDoubleAnimation sender = (BindableDoubleAnimation)s; 
      sender.internalAnimation.From = (double)e.NewValue; 
     }))); 


    public BindableDoubleAnimation() 
    { 
     internalAnimation = new DoubleAnimation(); 
    } 

    protected override double GetCurrentValueCore(double defaultOriginValue, double defaultDestinationValue, AnimationClock animationClock) 
    { 
     return internalAnimation.GetCurrentValue(defaultOriginValue, defaultDestinationValue, animationClock); 
    } 

    protected override Freezable CreateInstanceCore() 
    { 
     return internalAnimation.Clone();; 
    } 
} 

Tôi hiện được tự do sử dụng các ràng buộc cho thuộc tính Từ.

<local:BindableDoubleAnimation Storyboard.TargetProperty="Width" From="0" To="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Window}}"/> 
+0

Có ai nhận được điều này để làm việc cho 'BindableDoubleAnimation' s nằm bên trong 'Storyboard' có trong' VisualState' của 'ControlTemplate' không? Đối với các trường hợp mà tôi chỉ có một 'BindableDoubleAnimation' trong' VisualState' và tôi hardcode giá trị "To" (để nói một cái gì đó như "100"), không có gì được hoạt hình, và không phải 'GetCurrentValueCore' cũng không' CreateInstanceCore' đang được gọi . Đối với các trường hợp mà tôi sử dụng dữ liệu ràng buộc trên thuộc tính "Tới" thì liên kết luôn không thành công, luôn xuất lỗi "Không thể tìm nguồn để liên kết ...". Ngay cả khi tôi thử mọi thứ từ trên nguyên văn, nó vẫn thất bại. –

+0

... Tôi rất muốn làm việc này - có vẻ như nó có thể là một giải pháp tuyệt vời! –

2

Đó bindings không thể được sử dụng trong phim hoạt hình là một vấn đề thường gặp.

Một workaround sẽ được rằng bạn sử dụng một đối tượng helper trong đó có SourceValue & TargetValue (mà bạn có thể liên kết với bất cứ điều gì bạn muốn, bao gồm ActualWidth) một CurrentValue (mà trả về giá trị hoạt hình) và một Progress có thể được hoạt hình từ 0.0 đến 100.0. Khi tiến trình được thay đổi, bạn chỉ cần tính toán số CurrentValue mà sau đó bạn có thể liên kết Width đối tượng của mình. Nó không phải là đẹp nhưng nên làm việc.

+0

Tôi không rõ câu trả lời này. Bạn có thể cung cấp mẫu mã không? Bạn đang mô tả một cái gì đó tương tự như giải pháp @ Andy? –

+0

@PhillipScottGivens: Câu trả lời của Andy luôn thay đổi hình động bằng cách tạo một lớp có thể kết buộc trên đầu trang của nó. Những gì tôi đề nghị là khác nhau, tôi đề nghị một đối tượng trung gian luôn sử dụng cùng một hình động làm cho thuộc tính 'Progress' từ' 0' thành '100' (do đó hoạt ảnh không thay đổi), đối tượng này cung cấp giá trị hoạt ảnh thông qua' Thuộc tính CurrentValue' trả về giá trị được tính từ 'SourceValue',' TargetValue' và 'Progress' của nó. –

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