WPF画布-";活的";添加/删除子元素的预览

本文关键字:quot 元素 删除 添加 画布 活的 WPF | 更新日期: 2023-09-27 18:00:51

在我的WPF应用程序中,我有一个for循环,单击按钮后会操纵Canvas控件。

for (var i = 0; i < numOfIterations; i++)
{
    swarm.iterate();
    myCanvas.Children.Clear();
    for (int j = 0; j < numCities - 1; j++)
    {
        Line line = new Line();
        line.Stroke = System.Windows.Media.Brushes.Black;
        line.X1 = ScaleX(cities[swarm._gbestlist[j]].x, maxX);
        line.X2 = ScaleX(cities[swarm._gbestlist[j + 1]].x, maxX);
        line.Y1 = ScaleY(cities[swarm._gbestlist[j]].y, maxY);
        line.Y2 = ScaleY(cities[swarm._gbestlist[j + 1]].y, maxY);
        line.StrokeThickness = 2;
        myCanvas.Children.Add(line);
    }
}

正如您可能知道的,UI在循环执行期间没有响应,并且在循环完成后,上次迭代后的结果是可见的。我应该怎么做才能对添加和删除的行进行"实时"预览?

我尝试使用BackgroundWorker:

private void worker_DoWork(object sender, DoWorkEventArgs e)
{
    double maxX = FindMaxX();
    double maxY = FindMaxY();
    for (int i = 0; i < 250; i++)
    {
        swarm.iterate();
        RemoveLines();
        for (int j = 0; j < cities.Count - 1; j++)
        {
            Line line = new Line();
            line.Stroke = System.Windows.Media.Brushes.Black;
            line.X1 = ScaleX(cities[swarm._gbestlist[j]].x, maxX);
            line.X2 = ScaleX(cities[swarm._gbestlist[j + 1]].x, maxX);
            line.Y1 = ScaleY(cities[swarm._gbestlist[j]].y, maxY);
            line.Y2 = ScaleY(cities[swarm._gbestlist[j + 1]].y, maxY);
            line.StrokeThickness = 2;  
            myCanvas.Children.Add(line);
        }
    }
}

但我有

系统。用户代码未处理InvalidOperationException:调用线程无法访问此对象,因为其他线程拥有它。

WPF画布-";活的";添加/删除子元素的预览

您仍然可以使用应用程序调度器异步执行。此外,如果像Sinatr建议的那样,使用计时器将迭代划分为多个步骤,则可以获得所需的效果。

Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal,new           
Action(DoWork)

希望能有所帮助。