문제

I'm trying to update a BitmapImage in the UI from a BackgroundWorker thread. 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.

When I set

So far it looks like this:

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();
    }
}
도움이 되었습니까?

해결책

The problem is you are trying to update a UI element from a background thread. You cannot interact with elements created on the UI thread from any other thread because of security reasons. If you want to update the UI from a background thread, do something like this:

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

This method will create the bridge that allows you to talk to the UI thread. Check out this stackoverflow thread that has more example.

Best of Luck

다른 팁

use ObservableCollection like this:

 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:

<ListBox HorizontalAlignment="Left" ItemsSource="{Binding MyProperty}" Height="224" Margin="93,50,0,0" VerticalAlignment="Top" Width="321"/>
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top