带UI的线程(画布)

时间:2013-06-25 15:56:45

标签: c# wpf multithreading wpf-controls

我正在尝试为我现有的多幅绘图的重绘功能生成一个Thread。我在这里读到有可能在线程中可以实现UI看到这里LINK但是我不能在我的redrawSingelPoly()函数上使用它....任何想法如何使用redrawSingelPoly()作为线程?

在我的MainWindow.xaml.cs中:

当用户按下主窗口上的按钮时调用:

    private void SingleSelectedMeasurement(object sender, RoutedEventArgs e)
    {
        System.Windows.Controls.Button button = (System.Windows.Controls.Button)sender;
        RedrawSingelMeasurement(Convert.ToInt16(button.Tag));
    }

    private void RedrawSingelMeasurement(int selectedMeasurement)
    {
        selectedMeasurement = selectedMeasurement - 1;

        for (int i = 0; i < measurements.Length; i++)
        {
            if (selectedMeasurement != i) 
            {
                measurements[i].draw = false; //block drawing
            }
            else
            {
                measurements[i].draw = true; // remove block for drawing
            }
        }
            measurements[selectedMeasurement].redrawSingelPoly(); 
    }

在我的Measurement.cs中:

    public void redrawSingelPoly() 
    {
        Polyline poly = new Polyline();
        poly.Stroke = colorBrush; 
        poly.StrokeThickness = basicLineThick;

        //first clean all
        coordinateSystem.Children.Clear(); 

        poly.Points = points;
        //draw
        coordinateSystem.Children.Add(poly);
    }

4 个答案:

答案 0 :(得分:0)

您无法从与其相关的线程不同的线程访问DependencyObject的DependencyProperties(在您的情况下:coordinateSystem)。

如果你想加速你的应用程序,你应该创建自定义控件,覆盖它的OnRender方法并在那里绘制自定义图形:它将删除许多逻辑和可视树逻辑,并将更快地工作。

答案 1 :(得分:0)

理想情况下,一个窗口只能在一个Dispatcher上运行,但是您可以通过HostVisual在不同的线程中放置不同的视觉效果,但是在非常有限的情况下。也许这篇文章可以帮到你:

http://blogs.msdn.com/b/dwayneneed/archive/2007/04/26/multithreaded-ui-hostvisual.aspx

答案 2 :(得分:0)

你提到的文章谈到的实际上只是每个窗口都有一个帖子。不可能在不同的线程中绘制专用元素。

答案 3 :(得分:0)

private void SingleSelectedMeasurement(object sender, RoutedEventArgs e)
{
    var button = (System.Windows.Controls.Button)sender;

    Task.Factory.StartNew (
       () => OnUi(RedrawSingelMeasurement(Convert.ToInt16(button.Tag))));        
}

//here's a sample on how to get despatcher for the ui thread
private void OnUi (Action action)
    {
        if (_dispatchService == null) 
            _dispatchService = ServiceLocator.Current.GetInstance<IDispatchService>();
            //or _dispatchService  = Application.Current.Dispatcher - whatever is suitable

        if (_dispatchService.CheckAccess())
            action.Invoke ();
        else
            _dispatchService.Invoke(action);
    }