2012-11-23 24 views
1

我正在使用WPF和C#制作应用程序。我想要做的是在按下按钮之间在一段时间内在画布上打印大量形状。在我按下按钮的时候,一切都立即弹出。我已经尝试在每个“打印”之间休息一段时间,但这并没有帮助,只需要一段时间才能立即启动。我想要的是,形状每次弹出一个,让我们说0.5秒。代码如下:定期打印形状

private void Create_Click(object sender, RoutedEventArgs e) 
    { 
     Random random = new Random(); 
     for (int i = 0; i < 50; i++) 
     { 
      Thread.Sleep(500); 
      Path f = FlowerFactory.createFlower(FlowerBP, true); 
      Canvas.SetLeft(f, random.Next(0, 1650)); 
      Canvas.SetTop(f, random.Next(0,1000)); 
      DrawBoard.Children.Add(f); 
     }} 

回答

3

您需要,第一,运行循环在后台线程,以便它不会阻止更新UI;其次,将UI渲染任务发送回UI线程。对于第一个,你可以使用Task.Factory.StartNew,并为第二,使用Dispatcher.Invoke

Random random = new Random(); 
Task.Factory.StartNew(() => 
{ 
    for (int i = 0; i < 50; i++) 
    { 
     Thread.Sleep(500); 
     Dispatcher.Invoke(DispatcherPriority.Render, new Action(() => 
     { 
      Path f = FlowerFactory.createFlower(FlowerBP, true); 
      Canvas.SetLeft(f, random.Next(0, 1650)); 
      Canvas.SetTop(f, random.Next(0,1000)); 
      DrawBoard.Children.Add(f); 
     })); 
    } 
}); 
+1

最好的,只是做了:)我不是很用=>使用,但我会考虑它(拉姆达?)。非常感谢 – Abris

+0

不错的解决方案,但Task Library是Framework 4.5的一部分。同时可以单独包含它。 – RredCat

+1

@RredCat我认为你的意思是4.0 ...我从来没有在4.5,我可以使用它。也许你正在考虑异步/等待的东西,这是4.5? – McGarnagle

1

这是错误的决定睡你的主线程负责图形用户界面,。

尝试使用DispatchTimer。例如:

DispatcherTimer m_dispatcherTimer = new DispatcherTimer(); 
int m_count = 50; 

private void Init() 
{ 
    m_dispatcherTimer.Tick += new EventHandler(OnTick); 
    m_dispatcherTimer.Interval = new TimeSpan(0, 0, 1); 
} 

private void Create_Click(object sender, RoutedEventArgs e) 
{ 
    m_count = 50; 
    m_dispatcherTimer.Start(); 
} 

private void OnTick(object sender, EventArgs e) 
{ 
    // Draw your shapes here 

    if(0>=--m_count) 
    { 
     m_dispatcherTimer.Stop(); 
    } 
} 
+0

它工作正常,但我更喜欢dBasemans解决方案,因为它让我在这种情况下保留我的for循环,但我可以想象我将在稍后使用此解决方案。谢谢! :) – Abris

+0

@Abris你是对的。 dBasemans解决方案看起来更加优雅。 – RredCat

0
using System.Reactive.Concurrency; 
using System.Reactive.Linq; 
... 
var subscription = Observable.Interval(TimeSpan.FromSeconds(0.5)).Take(50).Subscribe(x=>CreateRandomFlower);