【问题标题】:Updating Bitmap from BackgroundWorker in MVVM/WPF从 MVVM/WPF 中的 BackgroundWorker 更新位图
【发布时间】:2014-05-04 03:58:34
【问题描述】:

我正在尝试从 BackgroundWorker 线程更新 UI 中的 BitmapImage。我对后台工作人员有足够的了解,可以对其进行一般设置,以及如何使用 ObservableCollection 从 BackgroundWorker 更新列表,但我正在努力更新图像。

当我设置时

到目前为止,它看起来像这样:

XAML:

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

视图模型:

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();
    }
}

【问题讨论】:

    标签: c# wpf mvvm bitmap backgroundworker


    【解决方案1】:

    问题是您正在尝试从后台线程更新 UI 元素。由于安全原因,您不能与任何其他线程在 UI 线程上创建的元素进行交互。如果您想从后台线程更新 UI,请执行以下操作:

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

    此方法将创建允许您与 UI 线程对话的桥梁。查看有更多示例的this stackoverflow 线程。

    祝你好运

    【讨论】:

    • 这很好用,谢谢。我实际上了解 Dispatchers 现在是如何工作的。 Application.Current.Dispatcher.Invoke(() => ImageSource = UpdateImage());
    【解决方案2】:

    像这样使用 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);
           }
        }
    }
    

    和 xaml:

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

    【讨论】:

    • 我在原帖中简要提到过,但我知道如何使用 ObservableCollection 来更新列表。是否可以使用它们仅更新图像源绑定,因为它只需要一个对象而不是列表/集合?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-29
    • 1970-01-01
    • 1970-01-01
    • 2019-01-19
    • 1970-01-01
    • 1970-01-01
    • 2011-08-25
    相关资源
    最近更新 更多