错误:即使使用Dispatcher,也必须在与DependencyObject相同的线程上创建DependencySource [英] Error: Must create DependencySource on same Thread as the DependencyObject even by using Dispatcher

查看:923
本文介绍了错误:即使使用Dispatcher,也必须在与DependencyObject相同的线程上创建DependencySource的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我的View的一部分,其中我已将图像绑定到我的ViewModel中的属性:

The following is part of my View in which I have bound an Image to a property in my ViewModel:

<Image Source="{Binding Image}"  Grid.Column="2" Grid.ColumnSpan="2"/>

我的ViewModel是这样的:

public class MainWindowViewModel : INotifyPropertyChanged
{
    public BitmapImage Image
    {
        get { return _image; }
        set
        {
            _image = value;
            OnPropertyChanged();
        }
    }

    Action _makeScannerAlwaysOnAction;
    private BitmapImage _image;


    public MainWindowViewModel()
    {
        AddNewPersonCommand = new RelayCommand(OpenFrmAddNewPerson);
        FingerPrintScannerDevice.FingerPrintScanner.Init();
        MakeScannerAlwaysOn(null);
    }

    private void MakeScannerAlwaysOn(object obj)
    {
        _makeScannerAlwaysOnAction = MakeScannerOn;
        _makeScannerAlwaysOnAction.BeginInvoke(Callback, null);
    }

    private void Callback(IAsyncResult ar)
    {
        FingerPrintScannerDevice.FingerPrintScanner.UnInit();
        var objFingerPrintVerifier = new FingerPrintVerifier();
        objFingerPrintVerifier.StartVerifingProcess();
        var ms = new MemoryStream();
        ms.Position = 0;
        objFingerPrintVerifier.MatchPerson.Picture.Save(ms, ImageFormat.Png);
        var bi = new BitmapImage();
        bi.BeginInit();
        bi.StreamSource = ms;
        bi.EndInit();
        Thread.Sleep(2000);
        Dispatcher.CurrentDispatcher.Invoke(() => Image = bi);
        //Image = bi;

        _makeScannerAlwaysOnAction.BeginInvoke(Callback, null);
    }

    private void MakeScannerOn()
    {
        while (true)
        {
            if (FingerPrintScannerDevice.FingerPrintScanner.ScannerManager.Scanners[0].IsFingerOn)
            {
                return;
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

我的问题: 问题是当我想绑定图像时,它给了我错误

My Problem: The problem is when I want to bind the Image it gives me the error

必须在与DependencyObject相同的线程上创建DependencySource

Must create DependencySource on same Thread as the DependencyObject

我在Google上搜索了很多东西,并且看到了SO上的帖子,但是他们都不适合我.

I have googled a lot and I have seen the post in SO but neither of them worked for me.

任何帮助将不胜感激.

推荐答案

BitmapImageDependencyObject,所以在哪个线程上创建它并不重要,因为除非您不能访问在另一个线程上创建的对象的DependencyProperty,否则这是一个 Freezable 对象,您可以 Freeze 它.

BitmapImage is DependencyObject so it does matter on which thread it has been created because you cannot access DependencyProperty of an object created on another thread unless it's a Freezable object and you can Freeze it.

使当前对象不可修改,并将其IsFrozen属性设置为true.

Makes the current object unmodifiable and sets its IsFrozen property to true.

您需要做的是在更新Image之前致电Freeze:

What you need to do is call Freeze before you update Image:

bi.BeginInit();
bi.StreamSource = ms;
bi.EndInit();
bi.Freeze();

Dispatcher.CurrentDispatcher.Invoke(() => Image = bi);

正如@AwkwardCoder指出的,

可冻结对象概述

as pointed out by @AwkwardCoder here is Freezable Objects Overview

这篇关于错误:即使使用Dispatcher,也必须在与DependencyObject相同的线程上创建DependencySource的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆