感谢@GlennWatson指出我需要添加对Nuget软件包
我有一个
我意识到下面的代码不符合MVVM规范,因为我在视图模型中使用了'显式引用/实例化视图的类型'的代码,但我只是在寻找一个最小的可行示例,以便我可以往回工作,将视图和视图模型代码分开,并最终传递一个服务到我的视图模型,处理整个“选择文件路径”的部分。
正如我之前提到的,我尝试了很多不同的选项,包括将服务注入到我的视图模型中,但无论我在哪里实例化
我还通过Google搜索“ReactiveUI”和“OpenFileDialog”,但我找到的代码似乎都不是最新的(例如使用
更新
感谢@GlennWatson指出我需要添加对Nuget包
我添加它后,代码就可以工作了!
现在的代码看起来像这样,我相信它符合MVVM规范,使用依赖注入,并使用ReactiveUI的最新功能/最佳实践(虽然我显然接受批评!): ImportPdf
ReactiveUI.WPF
的引用,除了ReactiveUI
软件包。我有一个
ReactiveObject
视图模型,在其中我想使用一个OpenFileDialog
来设置我的视图模型属性之一(PdfFilePath
)的值。我尝试的所有方法都导致了一个“调用线程无法访问此对象,因为一个不同的线程拥有它”的错误。我意识到下面的代码不符合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
(例如在主视图中),我总是遇到相同的错误。我还通过Google搜索“ReactiveUI”和“OpenFileDialog”,但我找到的代码似乎都不是最新的(例如使用
ReactiveCommand<Unit,Unit>
),也与任何其他示例不一致!谢谢。更新
感谢@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;
}
}
}
更新
由于缺少相应的包,我还遇到了下面的错误:此CollectionView类型不支持来自与Dispatcher线程不同的线程对其SourceCollection进行更改