简体   繁体   English

在MVVM / WPF中从BackgroundWorker更新位图

[英]Updating Bitmap from BackgroundWorker in MVVM/WPF

I'm trying to update a BitmapImage in the UI from a BackgroundWorker thread. 我正在尝试从BackgroundWorker线程更新UI中的BitmapImage。 I know enough about background workers to generally set them up, and how to use an ObservableCollection to update a list from a BackgroundWorker, but I'm struggling getting the image to update. 我对背景工作者的了解非常了解,以及如何使用ObservableCollection从BackgroundWorker更新列表,但我很难让图像更新。

When I set 当我设置

So far it looks like this: 到目前为止它看起来像这样:

XAML: XAML:

<Image Source="{Binding ImageSource}" />

ViewModel: 视图模型:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void NotifyPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    private BitmapImage ImageSource_;
    public BitmapImage ImageSource
    {
        get { return ImageSource_; }
        set { ImageSource_= value; NotifyPropertyChanged("ImageSource"); }
    }

    private BackgroundWorker UpdateImageBGW = new BackgroundWorker();

    public ViewModel()
    {
        // this works fine
        ImageSource = UpdateImage();

        UpdateImageBGW.DoWork += new DoWorkEventHandler(UpdateImage_DoWork);
        UpdateImageBGW.RunWorkerAsync();
    }

    private void UpdateImage_DoWork(object sender, DoWorkEventArgs e)
    {
        // this gets called fine and grabs the updated image, but setting it to
        // ImageSource never updates the UI
        ImageSource = UpdateImage();
    }
}

use ObservableCollection like this: 像这样使用ObservableCollection:

 public partial class MainWindow : Window
{
    private ObservableCollection<int> myVar;

    public ObservableCollection<int> MyProperty
    {
        get { return myVar; }
        set { myVar = value; }
    }

    BackgroundWorker bw;
    public MainWindow()
    {
        InitializeComponent();
        this.DataContext = this;
        MyProperty = new ObservableCollection<int>();
        bw = new BackgroundWorker();
        bw.DoWork += bw_DoWork;
        bw.RunWorkerAsync();
    }

    void bw_DoWork(object sender, DoWorkEventArgs e)
    {
       for(int i = 0; i < 10;i++)
       {
           MyProperty.Add(i);
       }
    }
}

and xaml: 和xaml:

<ListBox HorizontalAlignment="Left" ItemsSource="{Binding MyProperty}" Height="224" Margin="93,50,0,0" VerticalAlignment="Top" Width="321"/>

The problem is you are trying to update a UI element from a background thread. 问题是您正在尝试从后台线程更新UI元素。 You cannot interact with elements created on the UI thread from any other thread because of security reasons. 由于安全原因,您无法与任何其他线程在UI线程上创建的元素进行交互。 If you want to update the UI from a background thread, do something like this: 如果要从后台线程更新UI,请执行以下操作:

Dispatcher.Invoke((Action)delegate() { /*update UI thread here*/ });

This method will create the bridge that allows you to talk to the UI thread. 此方法将创建允许您与UI线程通信的桥。 Check out this stackoverflow thread that has more example. 查看这个包含更多示例的stackoverflow线程。

Best of Luck 最好的运气

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM