Animuję zmianę rozmiaru obramowania w Silverlight, ale muszę również stopniowo usuwać margines wokół niego (obecnie 50). Mieszanka nie wydaje się generować animacji dla zmiany marginesu - po prostu przeskakuje od 50 do 0 za jednym razem. Czy istnieje sposób, aby to osiągnąć?Animate Margin Change w Silverlight
Odpowiedz
Problem polega na tym, że margines jest naprawdę typu "System.Windows.Thickness", który NIE jest obiektem zależności, w związku z czym lewy, górny, prawy i dolny NIE są zależne od właściwości, dlatego nie można ich animować za pomocą DoubleAnimation (które pozwala na animowanie).
Do animacji marży służy animacja obiektów, która nie zawiera animacji. Dlatego widzisz skok marginesu z pierwotnej lokalizacji do nowej lokalizacji. Innym typowym przykładem jest to samo, gdy próbujesz animować właściwość Visibility między Visible i Collapsed.
Musisz albo wykonać animację opartą na timerze, aby animować margines, albo zaimplementować własny typ animacji dla obiektów grubości.
Ben Lemmon daje eleganckie rozwiązanie: http://blogs.msdn.com/blemmon/archive/2009/03/18/animating-margins-in-silverlight.aspx
Here is an updated version który pozwala animować od wewnątrz XAML
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace NiceCards.Animations
{
public class ThicknessAnimationX
{
public static readonly DependencyProperty ElementProperty = DependencyProperty.RegisterAttached("Element", typeof(DependencyObject), typeof(DoubleAnimation), new PropertyMetadata(new PropertyChangedCallback(OnElementPropertyChanged)));
// The time along the animation from 0-1
public static DependencyProperty TimeProperty = DependencyProperty.RegisterAttached("Time", typeof(double), typeof(DoubleAnimation), new PropertyMetadata(OnTimeChanged));
// The object being animated
public static DependencyProperty TargetProperty = DependencyProperty.RegisterAttached("Target", typeof(DependencyObject), typeof(ThicknessAnimationX), null);
public static DependencyProperty TargetPropertyProperty = DependencyProperty.RegisterAttached("TargetProperty", typeof(DependencyProperty), typeof(DependencyObject), null);
public static readonly DependencyProperty FromProperty = DependencyProperty.RegisterAttached("From", typeof(Thickness), typeof(DoubleAnimation), null);
public static readonly DependencyProperty ToProperty = DependencyProperty.RegisterAttached("To", typeof(Thickness), typeof(DoubleAnimation), null);
public static void SetElement(DependencyObject o, DependencyObject value)
{
o.SetValue(ElementProperty, value);
}
public static DependencyObject GetElement(DependencyObject o)
{
return (DependencyObject)o.GetValue(ElementProperty);
}
private static void OnElementPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue != null)
{
DoubleAnimation doubleAnimation = (DoubleAnimation)d;
doubleAnimation.SetValue(TargetProperty, e.NewValue);
doubleAnimation.From = 0;
doubleAnimation.To = 1;
doubleAnimation.SetValue(TargetPropertyProperty, FrameworkElement.MarginProperty);
Storyboard.SetTargetProperty(doubleAnimation, new PropertyPath("(ThicknessAnimationX.Time)"));
Storyboard.SetTarget(doubleAnimation, doubleAnimation);
}
}
private static void OnTimeChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
DoubleAnimation animation = (DoubleAnimation)sender;
double time = GetTime(animation);
Thickness from = (Thickness)sender.GetValue(FromProperty);
Thickness to = (Thickness)sender.GetValue(ToProperty);
DependencyProperty targetProperty = (DependencyProperty)sender.GetValue(TargetPropertyProperty);
DependencyObject target = (DependencyObject)sender.GetValue(TargetProperty);
target.SetValue(targetProperty, new Thickness((to.Left - from.Left) * time + from.Left,
(to.Top - from.Top) * time + from.Top,
(to.Right - from.Right) * time + from.Right,
(to.Bottom - from.Bottom) * time + from.Bottom));
}
public static double GetTime(DoubleAnimation animation)
{
return (double)animation.GetValue(TimeProperty);
}
public static void SetTime(DoubleAnimation animation, double value)
{
animation.SetValue(TimeProperty, value);
}
public static Thickness GetFrom(DoubleAnimation animation)
{
return (Thickness)animation.GetValue(FromProperty);
}
public static void SetFrom(DoubleAnimation animation, Thickness value)
{
animation.SetValue(FromProperty, value);
}
public static Thickness GetTo(DoubleAnimation animation)
{
return (Thickness)animation.GetValue(ToProperty);
}
public static void SetTo(DoubleAnimation animation, Thickness value)
{
animation.SetValue(ToProperty, value);
}
}
}
a następnie można to zrobić w XAML
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Positions">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.2"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Left">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" NiceCards:ThicknessAnimationX.To="0,0,0,0" NiceCards:ThicknessAnimationX.Element="{Binding ElementName=rectangle1}" Storyboard.TargetName="rectangle1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Right">
<Storyboard>
<DoubleAnimation Duration="0:0:0.3" NiceCards:ThicknessAnimationX.To="0,200,0,0" NiceCards:ThicknessAnimationX.Element="{Binding ElementName=rectangle1}" Storyboard.TargetName="rectangle1" Storyboard.TargetProperty="Opacity"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Rectangle Height="100" HorizontalAlignment="Left" Margin="23,25,0,0" x:Name="rectangle1" Stroke="Black" StrokeThickness="1" VerticalAlignment="Top" Width="200" Fill="#FF1BAA00"/>
pamiętać, że jeśli nie ustawiasz właściwości Target na DoubleAnimation w XAML, nie będziesz w stanie wyświetlić kontrolki/strony w Blend. Aby to naprawić, po prostu dodaj fałszywą właściwość target (w powyższym kodzie dodałem właściwość nieprzezroczystości, która jest wartością podwójną), i to będzie i przesłonięte w czasie wykonywania.
- 1. Animate Expander w WPF
- 2. Animacja Margin/Grubość
- 3. jak używać ważne w jQuery animate() funkcji
- 4. CSS Sticky Footer Margin
- 5. Margin/Padding w procentach w XML
- 6. Wiązanie płótna w silverlight
- 7. jquery animate pozycja w procentach
- 8. Utwórz jQuery Margin adder klasy
- 9. CSS margin-top nie działa w IE7
- 10. .animate z krzywą
- 11. WPF - Animate ListBox.ScrollViewer.HorizontalOffset?
- 12. Java Animate JLabel
- 13. Jquery animate bottom problem
- 14. ToggleClass animate jQuery?
- 15. Change Notification Balon Rozmiar
- 16. Animate intrinsicContentSize changes
- 17. C# TabControl TabPage Change
- 18. css: margin-top powoduje scrollbar
- 19. Silverlight DragDrop.DoDragDrop()
- 20. angularjs timepicker ng-change
- 21. Osi Change mydło: adres
- 22. Change Primary Key
- 23. Change display enum
- 24. Change "Lista ogłoszeń" text
- 25. jquery change div text
- 26. Czy możemy zdefiniować min-margin i max-margin, max-padding i min-padding w css?
- 27. jQuery animate scroll
- 28. Matplotlib animate fill_between shape
- 29. Animate MaxLines i Ellipsize
- 30. Gerrit odtwarza change-idy
Próbowałem użyć tego w XAML, jak na twoje przykład i otrzymuję strumień błędów w SL5. Dodałem deklarację 'xmlns: someName', ale wygląda na to, że XAML nie wie, jaka jest własność' someName: ThicknessAnimationX'. – Shaamaan