سؤال

لدي لوحة عمل بسيطة جدًا تحتوي على Int32Animation والتي تستهدف DP مخصصًا في صفي.

لدي رد اتصال OnChanged لـ DP الخاص بي، والذي يقوم بتنفيذ Console.WriteLine("القيمة الحالية:" + مي دي بي).

عندما أقوم بتشغيل لوحة العمل، يمكنني رؤية مخرجات وحدة التحكم بشكل جيد، وعندما أقوم بإيقاف لوحة العمل مؤقتًا، يتوقف إخراج وحدة التحكم، ولكن عندما أستأنف لوحة العمل، فإن DP ليست القيمة التالية التي يجب أن تكون عليها.ويستمر في الزيادة على الرغم من توقف القصة المصورة.

هل حدث لأحدهم شيء مثل هذا؟

إليك مقتطف التعليمات البرمجية لما أفعله

            Int32Animation element = new Int32Animation();
            element.From = 0;
            element.To = targetTo;
            element.Duration = dur;
            Storyboard.SetTargetProperty(element, new PropertyPath(CurrentFrameProperty));
            _filmstripStoryboard = new Storyboard {SpeedRatio = this.FrameRate};
            _filmstripStoryboard.Children.Add(element);


        public void Start()
        {
            _filmstripStoryboard.Begin(this, true);
        }

        public void Pause()
        {
            _filmstripStoryboard.Pause(this);
        }

        public void Unpause()
        {
            _filmstripStoryboard.Resume(this);
        }
هل كانت مفيدة؟

المحلول

هناك الموضوع في منتديات MSDN حيث تؤكد Microsoft أن هذا السلوك (استمرار القيمة الحالية حتى عند إيقاف لوحة العمل مؤقتًا لفترة من الوقت) هو خطأ في الإصدار الحالي (اعتبارًا من عام 2006) من WPF.يتضمن موضوع المنتدى حلاً بديلاً مقترحًا، على وجه التحديد، حفظ الموضع الحالي عند التوقف مؤقتًا، والعودة يدويًا إلى نفس الموضع عند الاستئناف.

يذكر الموضوع أنهم كانوا يفكرون في إصلاح الخلل في إصدار مستقبلي، لكنني لا أعرف ما إذا كان .NET 3.5 أو 4.0 قد أصلح هذا الخلل بالفعل أم لا.

يحرر: يبدو أنه تم إصلاح الخلل في .NET 4.0 - لقد تمكنت من إيقاف الرسم المتحرك مؤقتًا ثم استئنافه دون الانتقال إلى الأمام عبر الوقت الفاصل.(لم أختبر في 3.5.)

نصائح أخرى

والآن ليس هناك خطأ في 4.0. رمز أدناه يعمل بشكل جيد.

<Window
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="WpfAnimation.Win1805787"
    xmlns:Local="clr-namespace:WpfAnimation"
    x:Name="MyWindow"
    Title="Win1805787"
    Width="640" Height="480">

    <Grid x:Name="LayoutRoot">      

        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <TextBox HorizontalAlignment="Right" VerticalAlignment="Top" Width="75" Text="{Binding CurrentFrame, ElementName=MyWindow}" Height="20" Margin="5,0,5,5"/>
            <Button x:Name="Play1" Content="Play" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Click="Play_Click" Margin="5,0,5,5"/>
            <Button x:Name="Pause1" Content="Pause" HorizontalAlignment="Right" VerticalAlignment="Top" Width="75" Click="Pause_Click" Margin="5,0,5,5"/>
            <Button x:Name="Resume1" Content="Resume" HorizontalAlignment="Right" VerticalAlignment="Top" Width="75" Click="Resume_Click" Margin="5,0,5,5"/>
        </StackPanel>

        </Grid>

</Window>   

و/////////////////////////

 using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;
    using System.Windows.Media.Animation;

    namespace WpfAnimation
    {
        /// <summary>
        /// Interaction logic for Win1805787.xaml
        /// </summary>
        public partial class Win1805787 : Window
        {
            public Win1805787()
            {
                this.InitializeComponent();

                _createStoryBoard();
                // Insert code required on object creation below this point.
            }

            public int CurrentFrame
            {
                get { return (int)GetValue(CurrentFrameProperty); }
                set { SetValue(CurrentFrameProperty, value); }
            }

            // Using a DependencyProperty as the backing store for CurrentFrame.  This enables animation, styling, binding, etc...
            public static readonly DependencyProperty CurrentFrameProperty =
                DependencyProperty.Register("CurrentFrame", typeof(int), typeof(Win1805787), 
                        new PropertyMetadata(0, new PropertyChangedCallback(OnValueChanged)));

            private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {

            }

            Storyboard _filmstripStoryboard;

            void _createStoryBoard()
            {       
                Int32Animation element = new Int32Animation();
                element.From = 0;
                element.To = 100;
                element.Duration = Duration.Plus(new Duration(new TimeSpan(1000000000)));
                Storyboard.SetTargetProperty(element, new PropertyPath(CurrentFrameProperty));
                _filmstripStoryboard = new Storyboard { SpeedRatio = 0.5 };
                _filmstripStoryboard.Children.Add(element);
            }

            private void Play_Click(object sender, System.Windows.RoutedEventArgs e)
            {
                _filmstripStoryboard.Begin(this, true);
            }

            private void Pause_Click(object sender, System.Windows.RoutedEventArgs e)
            {
                _filmstripStoryboard.Pause(this);
            }

            private void Resume_Click(object sender, System.Windows.RoutedEventArgs e)
            {
                _filmstripStoryboard.Resume(this);
            }

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