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

查看:41
本文介绍了错误:即使使用 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

我在谷歌上搜索了很多,我看到了 SO 中的帖子,但他们都没有为我工作.

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

非常感谢任何形式的帮助.

any kind of help would be very appreciated.

推荐答案

BitmapImageDependencyObject 所以它在哪个线程上创建很重要,因为你不能访问 <在另一个线程上创建的对象的代码>DependencyProperty 除非它是 Freezable 对象,您可以冻结它.

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天全站免登陆