在backgroundworker中显示WPF图像

时间:2011-02-09 09:42:37

标签: wpf picturebox

我正在使用WPF 3.5。

我在backgroundworker_DoWork事件中有while循环,它将连续从DSLR流式传输图像。

最初,流式图像将显示在PictureBox

<Grid>
    <WindowsFormsHost VerticalAlignment="Top" Background="Transparent" Height="500">
        <wf:PictureBox x:Name="picLiveView" />
    </WindowsFormsHost>
</Grid>

这是背后的代码:

        while (!liveViewExit)
        {
            try
            {
                if (picImage != null)
                    lock (mylock)
                    {
                        this.picLiveView.Image = (Image)picImage.Clone();
                    }
            }
            catch
            {

            }
        }

这很好用。

但是,当我尝试将PictureBox更改为WPF图像控件时,我将BitmapImage分配给WPF图像控件时出现此错误:

{“调用线程无法访问此对象,因为其他线程拥有它。”}

        MemoryStream ms = new MemoryStream();
        bmp.Save(ms, ImageFormat.Png);
        ms.Position = 0;
        BitmapImage bi = new BitmapImage();
        bi.BeginInit();
        bi.StreamSource = ms;
        bi.EndInit();

        try
        {
            if (bi != null)
            {
                this.imageBox.Source = bi;
            }
        }
        catch
        {

        }

为什么.NET 2 PictureBox控件在.NET 3.5 WPF图像控件没有的情况下工作?

我试过这段代码:

BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
    // load your data
    disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);

它没有任何错误,但图像不刷新。 while循环使应用程序无响应。

1 个答案:

答案 0 :(得分:2)

你需要在主线程中实例化一个Dispatcher对象,并在后台worker中使用它,调用它的Invoke方法。

以下是代码示例:

BackgroundWorker bg = new BackgroundWorker();
Dispatcher disp = Dispatcher.CurrentDispatcher;
bg.DoWork += (sender, e) =>
{
    // load your data
    disp.Invoke(new Action(/* a method or lambda that do the assignment */));
}
bg.RunWorkerCompleted += anotherMethodOrLambda; // optional
bg.RunWorkerAsync(/*an argument object that will be visible in e.Argument*/);