gpt4 book ai didi

c# - ReactiveUI WPF - 调用线程无法访问此对象,因为另一个线程拥有它

转载 作者:太空狗 更新时间:2023-10-30 01:13:01 26 4
gpt4 key购买 nike

感谢@GlennWatson 指出我需要添加对 Nuget 包的引用 ReactiveUI.WPF , 除了 ReactiveUI包。

我有一个 ReactiveObject查看模型,我想在其中使用 OpenFileDialog设置我的 View 模型属性之一的值 ( PdfFilePath )。我尝试过的所有结果都是 The calling thread cannot access this object because a different thread owns it错误。

我意识到下面的代码不符合 MVVM,因为我在 View 模型中使用的代码“明确引用/实例化 View 的类型”,但我只是在寻找一个可行的最小示例,这样我就可以向后工作,将 View 和 View 模型代码分开,并最终将服务传递给我的 View 模型,该服务处理整个“选择文件路径”部分。

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

正如我提到的,我尝试了很多不同的选项,包括将服务注入(inject)我的 View 模型,但无论我在哪里实例化 OpenFileDialog (例如在主视图中),我总是以同样的错误结束。

我也用谷歌搜索了“ReactiveUI”和“OpenFileDialog”,但我找到的代码似乎都不是最新的(例如使用 ReactiveCommand<Unit, Unit> ),也不与任何其他示例一致!谢谢。


更新

感谢@GlennWatson 指出我需要添加对 Nuget 包的引用 ReactiveUI.WPF , 除了 ReactiveUI包。

我一添加它,代码就起作用了!

代码现在看起来像这样,我相信它符合 MVVM,使用依赖注入(inject),并使用 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; }
}

IIO服务

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

更新

我也遇到过由于相同的丢失包引起的以下错误... This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread

最佳答案

如果在 WPF 或 WinForms 平台上运行,您需要确保包含对 ReactiveUI.WPF 或 ReactiveUI.Winforms 的 nuget 引用。

关于c# - ReactiveUI WPF - 调用线程无法访问此对象,因为另一个线程拥有它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53170592/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com