إزالة القصة المصورة ولكن الحفاظ على قيمة الرسوم المتحركة؟
-
18-09-2019 - |
سؤال
كيف يمكنني إزالة لوحة العمل في XAML (أي إجراء الإزالة في DataTrigger) ولكن الحفاظ على القيمة التي كانت الرسوم المتحركة. مشابهه ل animatable.beginanimation.:
إذا كان بداية الرسوم المتحركة فارغة، فسيتم إزالة أي رسوم متحركة حالية وسيتم الاحتفاظ بالقيمة الحالية للمطالبة.
المحلول
الاستخدام الأساسي ل RemovEstoryBoard هو إزالة القيم المتحركة وتعيدها إلى حالتها غير المتحركة. في معظم الحالات، يمكنك فقط إيقاف تشغيل المكالمة إلى pausestoryboard أو stopstoryboard بدلا من ذلك، اعتمادا على الحالة المحددة. الاستثناء الوحيد هو عندما تحتاج إلى تحرير الموارد التي تعقدها القصة المصورة أو استخدامها لغرض آخر.
إذا كنت ترغب حقا في إزالة لوحة العمل والحفاظ على قيم الخاصية، فيجب عليك تعيين القيم المتحركة مباشرة على الخصائص. يمكن القيام بذلك عن طريق تحديد كل قيمة إلى القيمة المتحركة، شيء مثل هذا:
void CopyAnimatedValuesToLocalValues(DependencyObject obj)
{
// Recurse down tree
for(int i=0; i<VisualTreeHelper.GetChildrenCount(obj); i++)
CopyAnimatedValuesToLocalValues(VisualTreeHelper.GetChild(obj, i));
var enumerator = obj.GetLocalValueEnumerator();
while(enumerator.MoveNext())
{
var prop = enumerator.Current.Property;
var value = enumerator.Current.Value as Freezable;
// Recurse into eg. brushes that may be set by storyboard, as long as they aren't frozen
if(value!=null && !value.IsFrozen)
CopyAnimatedValuesToLocalValues(value);
// *** This is the key bit of code ***
if(DependencyPropertyHelper.GetValueSource(obj, prop).IsAnimated)
obj.SetValue(prop, obj.GetValue(prop));
}
}
اتصل بهذا الحق قبل إزالة لوحة العمل لنسخ القيم المتحركة.
يحرر تم إجراء تعليق أن هذا الرمز قد يكون غير ضروري لأن الدعوة بالبند مع البداية = لا شيء يحقق تأثير مماثل.
في حين أنه صحيح أن Beginanimation مع Begintime = NULL يجعلها تبدو كما لو أن القيم تم نسخها إلى المحلية، فإن دعوة لاحقة لإزالة الإزالة سوف تسبب القيم للعودة. وذلك لأن Beginanimation with begintime = null يؤدي إلى الاحتفاظ بالرسوم المتحركة السابقة لقيمها في انتظار بدء الرسوم المتحركة الجديدة، ولكن لا يفعل شيئا يؤثر على القيم المحلية.
يكتب الكود أعلاه في الواقع على القيم المحلية، لذلك يمكن إزالة جميع الرسوم المتحركة وستظل الكائنات قيمها الجديدة. لذلك إذا كنت ترغب حقا في الاتصال ب RemoveStoryBoard وما زلت تحتفظ بقيمك، فستحتاج إلى الكود الذي كتبته أعلاه أو شيء من هذا القبيل.
نصائح أخرى
كان لدي مشكلة مماثلة عند استخدام AnimationTimeline
. وبعد تحول أسهل حل لالتقاط Completed
الحدث في الكود وراء وقبل الاتصال BeginAnimation
مع ال null
المعلمة لإزالة الرسوم المتحركة، احصل على القيمة الحالية للخاصية واستخدامها لتعيينها.
هذا يحصل على آخر قيمة متحركة، ويضعها.
void OnCompleted( object sender, EventArgs args )
{
// Required to copy latest animated value to local value.
o.SomeValue = o.SomeValue;
o.BeginAnimation( SomeClass.SomeValueProperty, null );
}