ReactiveUI WPF - вызывающий поток не может получить доступ к этому объекту, так как он принадлежит другому потоку - PullRequest
0 голосов
/ 06 ноября 2018

Спасибо @GlennWatson за указание, что мне нужно добавить ссылку на пакет Nuget ReactiveUI.WPF, в дополнение к пакету ReactiveUI.

У меня есть ReactiveObject модель представления, в которой я хотел бы использовать OpenFileDialog, чтобы установить значение одного из моих свойств модели представления (PdfFilePath). Все, что я пробовал, приводит к ошибке The calling thread cannot access this object because a different thread owns it.

Я понимаю, что приведенный ниже код не совместим с MVVM, потому что я использую код, который «явно ссылается на тип / создает представление» в модели представления, но я просто ищу минимальный пример, который работает, чтобы я мог работать в обратном направлении, разделяя представление и код модели представления и, в конечном счете, передавая сервис моей модели представления, которая обрабатывает всю часть «выбор пути к файлу».

public class ImportPdfViewModel : ReactiveObject
{
    public ImportPdfViewModel()
    {
        SelectFilePathCommand = ReactiveCommand.Create(() =>
        {
            OpenFileDialog ofd = new OpenFileDialog() { };
            //
            if (ofd.ShowDialog() == DialogResult.OK)
                PdfFilePath = ofd.FileName;
        });
    }

    private string _PdfFilePath;
    public string PdfFilePath
    {
        get => _PdfFilePath;
        set => this.RaiseAndSetIfChanged(ref _PdfFilePath, value);
    }

    public ReactiveCommand SelectFilePathCommand { get; set; }
}

Как я уже упоминал, я пробовал множество различных опций, включая внедрение службы в мою модель представления, но независимо от того, где я создаю экземпляр OpenFileDialog (например, в главном представлении), я всегда получаю одну и ту же ошибку .

Я также погуглил "ReactiveUI" и "OpenFileDialog", но, похоже, ни один из кодов, которые я нашел, не устарел (например, с использованием ReactiveCommand<Unit, Unit>) и не соответствует ни одному другому примеру! Спасибо.


UPDATE

Спасибо @GlennWatson за указание на то, что мне нужно добавить ссылку на пакет Nuget ReactiveUI.WPF, в дополнение к пакету ReactiveUI.

Как только я его добавил, код заработал!

Код теперь выглядит следующим образом, который, я считаю, совместим с MVVM, использует внедрение зависимостей и использует новейшие функции / лучшие практики ReactiveUI (хотя я, очевидно, открыт для критики!):

ImportPdf

public class ImportPdfViewModel : ReactiveObject
{
    public ImportPdfViewModel(IIOService openFileDialogService)
    {
        SelectFilePathCommand = ReactiveCommand
            .Create(() => openFileDialogService.OpenFileDialog(@"C:\Default\Path\To\File"));
        SelectFilePathCommand.Subscribe((pdfFilePath) => { PdfFilePath = pdfFilePath; });
    }

    private string _PdfFilePath;
    public string PdfFilePath
    {
        get => _PdfFilePath;
        set => this.RaiseAndSetIfChanged(ref _PdfFilePath, value);
    }

    public ReactiveCommand<Unit, String> SelectFilePathCommand { get; set; }
}

IIOService

public interface IIOService
{
    string OpenFileDialog(string defaultPath);
}

OpenFileDialogService

public class OpenFileDialogService : IIOService
{
    public string OpenFileDialog(string defaultPath)
    {
        OpenFileDialog ofd = new OpenFileDialog() { FileName = defaultPath };
        //
        if (ofd.ShowDialog() == DialogResult.OK)
        {
            return ofd.FileName;
        }
        else
        {
            return null;
        }
    }
}

UPDATE

У меня также была ошибка ниже, вызванная тем же отсутствующим пакетом ... This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread

1 Ответ

0 голосов
/ 14 ноября 2018

Если вы работаете на платформе WPF или WinForms, вам необходимо убедиться, что вы включили ссылку на Nuget для ReactiveUI.WPF или ReactiveUI.Winforms.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...