【问题标题】:How to make one window wait for another before continuing?如何让一个窗口在继续之前等待另一个窗口?
【发布时间】:2014-08-07 16:10:04
【问题描述】:

我的程序进退两难。我的程序就像一个专门的计算器,概率,掷骰子类型的东西——想想自动 RPG 滚动。目前它在一个窗口上的设置方式它拥有所有数据并进行所有计算等,但我还有第二个可选窗口,它纯粹用于动画,所以它不仅仅是文本输出。现在动画窗口工作正常,我的“数据窗口”也没有更好的术语,当我想从我的数据窗口更新我的动画窗口并使数据窗口等待动画完成时,问题就变成了。

设置如下: 数据窗口运行一个方法,在该方法中它告诉动画窗口更新图像并运行故事板动画方法。这样可行。现在数据窗口运行一个具有 foreach 循环的方法,并且在该 foreach 循环中它告诉动画窗口更新它们的图像并为当前的 foreach 项目运行动画。简单吧?那么问题是数据窗口不耐烦并继续告诉动画窗口运行它的动画 - 而且由于动画应该回收图像对象,只是使用新源,使用该动画,动画窗口会忘记所有命令从数据窗口只运行最后一个,而不是一个接一个地运行。

所以基本上我的问题是 - 在继续 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 循环继续之前完成。

【问题讨论】:

    标签: c# wpf storyboard multi-window


    【解决方案1】:

    我建议使用 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 Class 示例。

    【讨论】:

    • 我试过了,但现在我得到错误“调用线程无法访问这个对象,因为另一个线程拥有它。”当我尝试更改 img_projectile 的来源时。不确定这是否是因为 bg,但你知道过去的任何方法吗?
    • 我也把它放在了 foreach 循环中,这可能是问题所在,如果是这样,那么我认为这对我不起作用。我需要在每个循环中运行一次动画,然后在同一个循环中执行更多计算。
    • 您可能需要查看 System.Threading.Timer 或 DispatcherTimer。这有很多 SO 链接,例如stackoverflow.com/questions/14354561/…
    • 无论哪种方式,我认为您需要某种线程,以便线程可以暂停(数据),而另一个完成(动画)
    • 我将如何使用它?在我看来,除非我可以暂停一个线程与另一个线程,否则计时器将无法工作——这正是我要问的问题。
    猜你喜欢
    • 1970-01-01
    • 2021-08-02
    • 2014-10-25
    • 1970-01-01
    • 2016-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多