ما هي أفضل طريقة لبدء الرسوم المتحركة عندما تتغير قيمة القيمة؟

StackOverflow https://stackoverflow.com/questions/1122177

سؤال

هذا هو الموقف الذي يأتي في كثير من الأحيان:

في طريقة العرض، لديك عنصر تحكم مرتبط بميزة ViewModel (مدعومة من قبل InotifyPropertyChanged). علي سبيل المثال:

<TextBlock Text="{Binding Path=Subtotal}"/>

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

الخيارات التالية تتبادر إلى الذهن:

  • ارفع حدثا إضافيا في ViewModel، اشترك في رمز العرض الخلف.
  • قم بإنشاء DataTrigger ملزمة بالعقار المذكورة باستخدام محول من شأنه أن يعود صحيحا إذا كانت القيمة تتغير.
  • قم بإنشاء DataTrigger ملزمة إلى خاصية منطقية جديدة على ViewModel والتي تستخدم "إشارة" التغيير.
  • قم بإنشاء سلوك متصل بالتحكم الذي يشترك في تغيير خاصية التحكم في عنصر التحكم وبدء الرسوم المتحركة.

أي واحد تحب / استخدامه؟ هل افتقد أي خيارات؟

ملاحظة: سيكون من الرائع (ولكن ليس حرجا) إذا كان الحل يوفر إمكانية بدء الرسوم المتحركة أولا وتعكس تغيير القيمة عند انتهاءه.

هل كانت مفيدة؟

المحلول

حسنا، هذا ما جئت إليه بعد بعض التجربة.

لقد قمت بإنشاء مزيج من التعبير 3 مشغلة بممتلكات التبعية (اسمه اشتراكه). أرتدي الاشتراك في نفس القيمة التي يرتبط بها TextBlock الخاصة بي، ويتم إرفاق هذا الزناد بمخزن التحكم في Expression Blend 3.

إليك الزناد:

public class DataTriggerPlus : TriggerBase<DependencyObject>
{
    public static readonly DependencyProperty SubscriptionProperty =
        DependencyProperty.Register("Subscription", 
            typeof(string),
            typeof(DataTriggerPlus),
            new FrameworkPropertyMetadata("",
              new PropertyChangedCallback(OnSubscriptionChanged)));

    public string Subscription
    {
        get { return (string)GetValue(SubscriptionProperty); }
        set { SetValue(SubscriptionProperty, value); }
    }

    private static void OnSubscriptionChanged(DependencyObject d,
      DependencyPropertyChangedEventArgs e)
    {
        ((DataTriggerPlus)d).InvokeActions(null);
    }
}

إليك كيفية إرفاقها بالقصة المصورة:

<TextBlock x:Name="textBlock" Text="{Binding TestProp}" Background="White">
    <i:Interaction.Triggers>
        <local:DataTriggerPlus Subscription="{Binding TestProp}">
            <im:ControlStoryboardAction 
                Storyboard="{StaticResource Storyboard1}"/>
        </local:DataTriggerPlus>
    </i:Interaction.Triggers>
</TextBlock>

أنا أحب هذا النهج كثيرا، ومزيج وظيفة كبيرة 3 المصممين!

تحرير: الإجابة على مرمى التعليق ...

نعم، يشحن مزيجا مزيجا. يمكنك فقط تضمين Microsoft.Expression.Interactions.dll و System.windows.interactivity في مشروعك.

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

نصائح أخرى

يمكنك إنشاء الزناد الذي سيبدأ الرسوم المتحركة.

شيء من هذا القبيل:

<Style>
    <Style.Triggers>
       <Trigger 
            Property="ViewModelProperty"
            Value="True">
            <Trigger.EnterActions>
                 <BeginStoryboard Storyboard="YourStoryBoard" />
            </Trigger.EnterActions>
       </Trigger>
    </Style.Triggers>
</Style>

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

لقد حاولت استخدام EventTriggers للربط بالأحداث المكتملة، ولكن هذا يقدم أيضا بعض المضاعفات. يرى هنا لمزيد من التفاصيل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top