0

プログラムにジレンマがあります。私のプログラムは、特殊な電卓、確率、ダイス ローラーのようなものです。自動化された RPG ローリングを考えてみてください。現時点では、1 つのウィンドウにすべてのデータがあり、すべての計算などを行うように設定されていますが、2 つ目のオプションのウィンドウもあり、これは純粋にアニメーション用であり、単なるテキスト出力ではありません。これで、アニメーション ウィンドウは正常に動作し、適切な用語がないための「データ ウィンドウ」と同様に、データ ウィンドウからアニメーション ウィンドウを更新し、アニメーションが完了するまでデータ ウィンドウを待機させたい場合に問題が発生します。

セットアップは次のとおりです。データ ウィンドウはメソッドを実行し、そのメソッド内でアニメーション ウィンドウに画像を更新し、ストーリーボード アニメーション メソッドを実行するよう指示します。それはうまくいきます。これで、データ ウィンドウは foreach ループを持つメソッドを実行し、その foreach ループで、アニメーション ウィンドウに画像を更新し、現在の foreach アイテムのアニメーションを実行するように指示します。シンプルですよね?問題は、データ ウィンドウがせっかちで、アニメーション ウィンドウにアニメーションを実行するように指示し続けることです。アニメーションは画像オブジェクトを新しいソースだけでリサイクルすることになっているため、アニメーション ウィンドウはすべての注文を忘れてしまいます。データ ウィンドウから、1 つずつ実行するのではなく、最後の 1 つだけを実行します。

基本的に私の質問は、foreach ループを続行する前に、アニメーション ウィンドウがストーリーボード アニメーションを終了するのをデータ ウィンドウに待機させるにはどうすればよいかということです。

私のコードの簡略化されたバージョンはこれです -

//In my data window
foreach (var item in Weapons)
{
try
            {
                string weapons = "\\" + weapon.Name + ".png";
                AnimationWindow.img_Pojectile.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\Images" + weapons));
            }
            catch
            {
                try
                {
                    string weapons = "\\" + weapon.Type + ".png";
                    AnimationWindow.img_Pojectile.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\Images" + weapons));
                }
                catch
                {
                    AnimationWindow.img_Pojectile.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\Images\\Default.png"));
                }
            }

    AnimationWindow.Fire(item.Name);
//More code stuff I have to repeat here, all the calculations and such...
}

//In my AnimationWindow
public void Fire(string name)
{
    img_Pojectile.Source = new BitmapImage(new Uri(Directory.GetCurrentDirectory() + "\\" + name + ".png"));
    Storyboard sb = new Storyboard();
    DoubleAnimation anim = new DoubleAnimation(0, 120, TimeSpan.FromSeconds(seconds));
    TranslateTransform trans = new TranslateTransform();
target.RenderTransform = trans;

anim.AutoReverse = true;
anim.RepeatBehavior = RepeatBehavior.Forever;
anim.BeginTime = TimeSpan.FromSeconds(offset);

Storyboard.SetTarget(anim, target);
Storyboard.SetTargetProperty(anim, new PropertyPath("(FrameworkElement.RenderTransform).(TranslateTransform.Y)"));

sb.Completed += (o, s) => {
//Figured a completed event might help, so far no luck
};

sb.Children.Add(anim);
sb.Begin();
}

したがって、この単純なバージョンでは、foreach ループが進む前にアニメーションが終了するようにしたいと考えています。

4

1 に答える 1

0

別のスレッドでサイコロを振る操作を実行するには、BackgroundWorker スレッドを使用することをお勧めします。アニメーションの完了後にRunWorkerCompletedメソッドが完了すると、アプリケーションで続行できます。

例えば

var bg = new BackgroundWorker();
            bg.DoWork += (s, e) =>
                             {
                                 // Do Dice roll animation
                                 // Disable data window 

                             };

            bg.RunWorkerCompleted += (s, e) =>
                            {
                               // Rice roll complete do other stuff
                               // Enable the data window
                            };

            bg.RunWorkerAsync();

また、MSDN BackgroundWorker クラスの例も確認してください。

于 2014-08-07T07:45:08.753 に答える