مشاركة عبر


خدع وتلميحات الرسومات التحركة

عند العمل مع حركات في WPF ، يوجد عدد من التلميحات والخدع التي يمكن أن تنفذها بشكل أفضل و توفر حدوث العطل الناتج.

مشاكل عامة

تحريك موضع المحرك الدائرى أو الشريط تجمد الصور

إذا تم تحريك موضع شريط التمرير أو المنزلق باستخدام حركة له على FillBehavior من HoldEnd (القيمة الافتراضية) ، لن يكون المستخدم قادراً على نقل شريط التمرير أو مربع التمرير. وهذا لأن حتى لو انتهت الحركة فإنه يتم تجاوز القيمة الأساسية لخاصية الهدف. لتوقيف الحركة من تجاوز قيمة الخاصية الحالية قم بإزالته أو إعطاءه FillBehavior من Stop. لمزيد من المعلومات وللحصول على مثال راجع كيفية القيام بما يلي: تعيين خاصية بعد تحريكها بلوحة العمل.

تحريك الناتج من الحركة ليس له تأثير

لا يمكن تحريك كائن اذا كان ناتج من حركة اخرى. على سبيل المثال، إذا كنت تستخدم ObjectAnimationUsingKeyFrames لتحريك Fill من Rectangle من RadialGradientBrush إلى SolidColorBrush ، لا يمكن تحريك أي خصائص من RadialGradientBrush أو SolidColorBrush.

لا يمكن تغيير قيمة الخاصية بعد الحركات عليه

في بعض الحالات، أنه قد يظهر أنك لا تستطيع تغيير قيمة الخاصية بعد أن تم تحريكها, حتى بعد انتهاء الحركة. وهذا لأن حتى لو انتهت الحركة فإنه يتم تجاوز القيمة الأساسية لخاصية الهدف. لتوقيف الحركة من تجاوز قيمة الخاصية الحالية قم بإزالته أو إعطاءه FillBehavior من Stop. لمزيد من المعلومات وللحصول على مثال راجع كيفية القيام بما يلي: تعيين خاصية بعد تحريكها بلوحة العمل.

تغيير الفترة الزمنية ليس له تأثير.

على الرغم من أن معظم خصائص Timeline قابلة للحركة، تغيير قيم Timeline النشطة يبدو أن ليس له تأثير. لأن ، عند بداية Timeline نظام توقيت يقوم بعمل نسخة Timeline و يستخدمه لإنشاء Clock الكائن. تعديل النسخة الاصلية أي تأثير على النسخة الخاصة بالنظام.

للحصول على Timeline لتعكس التغيرات، يجب إعادة إنشاء الساعة كما يستخدم ليحل محل ساعة إنشاؤها مسبقاً. الساعات لا يتم إعادة إنشاءها لك تلقائياً. هذه عدة طرق لتطبيق تغييرات المخطط الزمني:

  • إذا كان المخطط الزمني أو ينتمي إلى Storyboard ، يمكنك جعل هذه ليعكس التغييرات عن طريق إعادة تطبيق حال تعرّضه للتغيير من قبل لوحة العمل الخاصة به باستخدام طريقة BeginStoryboard أو Begin. ويكون لهذا تأثير الجانب أيضاً إعادة تشغيل الحركة. في التعليمة البرمجية ، يمكنك استخدام الأسلوب Seek لإزاحة لوحة العمل إلى الموضع السابق لها.

  • إذا قمت بتطبيق حركة مباشرة إلى خاصية باستخدام اسلوب BeginAnimation استدعى اسلوب BeginAnimation مرة أخرى ومررها للحركة التي تم تعديلها.

  • إذا كنت تعمل مباشرة في مستوى الساعة لإنشاء و تطبيق مجموعة جديدة من الساعات واستخدامها لاستبدال مجموعة من الساعات التي تم إنشاؤها.

لمزيد من المعلومات حول المخططات الزمنية الساعات راجع نظرة عامة على نظام الحركة و التوقيت.

لا تعمل FillBehavior.Stop كـ المتوقع

توجد أوقات عند إعداد خاصية FillBehavior إلى Stop يبدو يكون تأثير مثل متى حركة واحدة " خببhands" إلى آخر لأنه يحتوي على HandoffBehavior إعداد SnapshotAndReplace.

يقوم المثال التالي بإنشاء Canvas, a Rectangle و TranslateTransform. TranslateTransform سوف تحرك لنقل Rectangle حول Canvas.

<Canvas Width="600" Height="200">
  <Rectangle 
    Canvas.Top="50" Canvas.Left="0" 
    Width="50" Height="50" Fill="Red">
    <Rectangle.RenderTransform>
      <TranslateTransform 
        x:Name="MyTranslateTransform" 
        X="0" Y="0" />
    </Rectangle.RenderTransform>
  </Rectangle>
</Canvas>

تستخدم الأمثلة الموجودة في هذا المقطع الكائنات السابق إلى عرض العديد من الحالات حيث الخاصية FillBehaviorلا تسلك كما تتوقع .

"FillBehavior = "Stop و HandoffBehavior مع حركات متعددة

أحياناً يبدو كما لو أن الحركة تتجاهل خاصية FillBehavior عند استبدالها بواسطة حركة أخرى. انظر المثال التالي الذي يقوم بإنشاء كائنين من Storyboard ويستخدم لتحريك نفس TranslateTransform كما في المثال السابق.

أول Storyboard ، B1 ، يتحريك خاصية X TranslateTransform من 0 إلى 350 ، التي يتحرك 350 بكسل المستطيل إلى اليمين. عند وصول رسم متحرك إلى إنهاء مدته و إيقاف تشغيل، Xخاصية يعود إلى قيمته الأصلية، 0. ونتيجة لذلك، مستطيل التحديد ينتقل إلى وحدات البكسل لليمين 350 وثم ينتقل إلى موضعه الأصلي.

<Button Content="Start Storyboard B1">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard x:Name="B1">
          <DoubleAnimation 
            Storyboard.TargetName="MyTranslateTransform"
            Storyboard.TargetProperty="X"
            From="0" To="350" Duration="0:0:5"
            FillBehavior="Stop"
            />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

Storyboard ، B2 الثانية، تحرك أيضاً الخاصية X من نفس TranslateTransform. لأن فقط الخاصية To للحركة في هذا Storyboard تعيين ، يستخدم الحركة قيمة الخاصية بتحريك كـقيمة البداية .


<!-- Animates the same object and property as the preceding
     Storyboard. -->
<Button Content="Start Storyboard B2">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard x:Name="B2">
          <DoubleAnimation 
            Storyboard.TargetName="MyTranslateTransform"
            Storyboard.TargetProperty="X"
            To="500" Duration="0:0:5" 
            FillBehavior="Stop" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

إذا قمت بالنقر فوق الزر الثاني أثناء Storyboard تشغيل الاول ،توقع السلوك التالي:

  1. لوحة العمل الأولى ينتهي ويرسل المستطيل إلى موضعه الأصلي لأن الحركة تحتوي على FillBehavior من Stop.

  2. لوحة العمل الثانية نافذة المفعول و تحرك من الموضع الحالى ، و هو الآن 0 إلى 500.

ولكن ذلك لا يحدث.بدلاً من لا ينتقل المستطيل للخلف; فإنه يستمر نقل إلى اليمين. وذلك بسبب رسم متحرك الثاني يستخدم القيمة الحالي للحركة أول القيمة الابتدائية و تحريك من تلك القيمة إلى 500. When the second animation replaces the first because the SnapshotAndReplace HandoffBehavior is used, the FillBehavior of the first animation does not matter.

سلوك الملء و الأحداث المكتملة

توضح الأمثلة التالية سيناريو آخر حيث يبدو Stop FillBehaviorان ليس له تأثير. مرة أخرى، مثال يستخدم لوحة العمل لتحريك Xخاصية TranslateTransformمن 0 إلى 350. ومع ذلك، هذه المرة المثال تسجيل ل Completedحدث.

<Button Content="Start Storyboard C">
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Click">
      <BeginStoryboard>
        <Storyboard Completed="StoryboardC_Completed">
          <DoubleAnimation 
            Storyboard.TargetName="MyTranslateTransform"
            Storyboard.TargetProperty="X"
            From="0" To="350" Duration="0:0:5"
            FillBehavior="Stop" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

معالج الأحداثCompleted يبدأ تشغيل Storyboard آخر بتحريك نفس الخاصية من قيمته الحالية إلى 500.

        Private Sub StoryboardC_Completed(ByVal sender As Object, ByVal e As EventArgs)

            Dim translationAnimationStoryboard As Storyboard = CType(Me.Resources("TranslationAnimationStoryboardResource"), Storyboard)
            translationAnimationStoryboard.Begin(Me)
        End Sub
private void StoryboardC_Completed(object sender, EventArgs e)
{

    Storyboard translationAnimationStoryboard =
        (Storyboard)this.Resources["TranslationAnimationStoryboardResource"];
    translationAnimationStoryboard.Begin(this);
}

التالي هو العلامات يعرّف الثانية Storyboard كـالمورد.

<Page.Resources>
  <Storyboard x:Key="TranslationAnimationStoryboardResource">
    <DoubleAnimation 
      Storyboard.TargetName="MyTranslateTransform"
      Storyboard.TargetProperty="X"
      To="500" Duration="0:0:5" />
  </Storyboard>
</Page.Resources>

عند تشغيل Storyboard، قد تتوقع Xخاصية TranslateTransformلتحريك من 0 إلى 350، ثم العودة إلى 0 بعد إكمال (لأنه يحتوي على FillBehaviorإعداد Stop)، و ثم تحريك من 0 إلى 500. بدلاً من ذلك، TranslateTransformتحريك من 0 إلى 350 ثم إلى 500.

هذه نتيجة الترتيب الذي WPF رفع أحداث ونظرًا لأن قيم الخاصية تم تخزينها مؤقتاً ثم يتم إعادة حسابها ما لم يتم إبطالها. ان حدث يعالج اولا Completed لأنه تم المشغلة بواسطة المخطط الزمني الجذر ( Storyboardالأول). في هذا الوقت ، الخاصية X لا تزال ترجاع قيمته المتحركة حيث أنه لم يتم إبطاله حتى الآن. Storyboard الثاني يستخدم القيمة المخزنة مؤقتاً على أنها قيمة البداية ويبدأ للتحريك.

الأداء

الحركات تستكمل التشغيل بعد التنقل بعيد من صفحة

عند الانتقال من Page الذي يحتوي على حركة قيد التشغيل سيتم متابعة هذه تشغيل الحركة حتى يتم تجميع بيانات Page المهملة. بناءً على نظام التنقل التي تستخدمها ، الصفحة التي انتقلت منها قد تبقى في الذاكرة لفترة غير محددة من الوقت، كافة الموارد و حركاتها أثناء الإستهلاك الخاصة به. هذا الأكثر يمكن ملاحظته عند احتواء صفحة على تشغيل مستمر من الحركات ("ambient").

لهذا السبب، من الجيد استخدام الحدث Unloaded لإزالة الحركات عند التنقل بعيداً عن الصفحة.

هناك طرق مختلفة لإزالة حركة. يمكن استخدام الأساليب التالية لإزالة الحركات التي تنتمي إلى Storyboard.

قد يتم استخدام التقنية التالية بغض النظر عن كيفية بدء تشغيل الحركة.

  • لإزالة الحركة من خاصية محددة ، استخدام الاسلوب BeginAnimation(DependencyProperty, AnimationTimeline) . تحديد الخاصية التى يتم تحريكها كمعلمة الأولى و null كـالثانية. يؤدي هذا إلى إزالة كافة ساعات الحركة من الخاصية.

للحصول على مزيد من المعلومات حول الطرق المختلفة لتحريك الخصائص, راجع نظرة عامة حول أساليب تحريك الخاصية.

بإتستخدم HandoffBehavior تستهلك موارد النظام

عند تطبيق Storyboard, AnimationTimeline، أو AnimationClock لخاصية بإستخدام Compose HandoffBehaviorاى Clock الكائنات المقترنة مسبقاً مع الخاصية متابعة تستهلك موارد النظام; نظام توقيت لن يقوم بإزالة هذه الساعات تلقائياً.

لتجنب حدوث مشاكل الأداء عند تطبيق عدد كبير من الساعات باستخدام Compose ، يجب إزالة الساعات المكونة من الخاصية المتحركة بعد إكتمالهم. هناك عدة طرق لإزالة ساعة.

هذه مشكلة بشكل أساسي للحركات التي تحتوي على عمر طويل. عندما يتم تجميع البيانات المهملة أيضاً سيتم قطع الاتصال بساعته و تجمع البيانات المهملة.

لمزيد من المعلومات حول كائنات نظرة عامة على نظام الحركة و التوقيت، راجع .

راجع أيضًا:

المبادئ

نظرة عامة حول الحركة