3-1*_*264 5 c# mvvm reactive-programming reactiveui
感谢 @GlennWatson 指出ReactiveUI.WPF除了ReactiveUI包之外,我还需要添加对 Nuget Package 的引用。
我有一个ReactiveObject视图模型,我想在其中使用 anOpenFileDialog来设置我的一个视图模型属性 ( 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; }
}
Run Code Online (Sandbox Code Playgroud)
正如我提到的,我尝试了很多不同的选项,包括将服务注入我的视图模型,但无论我在哪里实例化OpenFileDialog(例如在主视图中),我总是以相同的错误告终。
我还用谷歌搜索了“ReactiveUI”和“OpenFileDialog”,但我发现的代码似乎都不是最新的(例如使用ReactiveCommand<Unit, Unit>),也不与任何其他示例一致!谢谢。
更新
感谢 @GlennWatson 指出ReactiveUI.WPF除了ReactiveUI包之外,我还需要添加对 Nuget Package 的引用。
一旦我添加它,代码就起作用了!
代码现在看起来像这样,我认为它符合 MVVM,使用依赖注入,并使用 ReactiveUI 的最新功能/最佳实践(尽管我显然很容易受到批评!):
导入PDF
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; }
}
Run Code Online (Sandbox Code Playgroud)
服务
public interface IIOService
{
string OpenFileDialog(string defaultPath);
}
Run Code Online (Sandbox Code Playgroud)
打开文件对话框服务
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
更新
我也遇到了由相同丢失的包引起的以下错误...... This type of CollectionView does not support changes to its SourceCollection from a thread different from the Dispatcher thread
| 归档时间: |
|
| 查看次数: |
591 次 |
| 最近记录: |