在ReactiveUI Avalonia (MVVM)中显示ViewModel的对话框



我有Window,继承ReactWindow,它连接到它的Viewmodel

一切都像预期的那样工作(绑定,点击内容,点击命令)。所以它起作用了。(代码如下)

当想要显示一个文件浏览器对话框,API想要一个Window对象作为ShowAsync(window)的参数,我没有在ViewModel类。

一个选项是从窗口本身做所有事情,但这违背了MVVM的目的,所以我的另一个选项是将视图转发给视图模型,但这似乎也很奇怪。

我也尝试过(正如你在下面的代码中看到的)添加一个参数到命令,这样视图就可以转发它,但是当你在WhenActivated中设置它时,你不能提供一个参数,所以我有点卡在这里。

我该怎么办?

这是视图模型

public class BatchManagementViewModel : ViewModelBase
{

public string BrowseText => "Browse/Edit files...";
public ReactiveCommand<BatchManagementView, Unit> BrowseCommand { get; set; }
public BatchManagementViewModel()
{   
BrowseCommand = ReactiveCommand.CreateFromTask( async () => ShowFileDialog(/*THE VIEW HERE ?*/));
}

async Task<string[]?> ShowFileDialog(BatchManagementView view)
{
// view is null here so it obviously crashes on ShowAsync
//but it's a param of the Command
var dialog = new OpenFileDialog();
dialog.AllowMultiple = true;
dialog.Title = DialogTitle;
dialog.Filters.AddRange(
new FileDialogFilter[]
{
new() {Name = "image files", Extensions = { ".png", ".jpg", ".jpeg", ".tiff" }}
}
);

return await dialog.ShowAsync(view);
}    
}

视图/窗口

public partial class BatchManagementView : ReactiveWindow<BatchManagementViewModel>
{
public BatchManagementView()
{
InitializeComponent();
this.WhenActivated(d =>
{
this.OneWayBind(ViewModel, 
viewModel => viewModel.BrowseText, 
view => view.BrowseButton.Content)
.DisposeWith(d);

this.OneWayBind(ViewModel, 
viewModel => viewModel.BrowseCommand, 
view => view.BrowseButton.Command)
.DisposeWith(d);
});
}
}

我应该在这里做什么?我觉得我想实现一些简单的东西,但我找不到一个例子与响应/MVVM在文档。

阅读交互。基本上你所做的是在视图模型中创建一个交互,它包括对话框的输入和输出。然后在窗口后面的代码中,为这个交互注册一个处理程序,该处理程序处理打开对话框。详见:https://docs.avaloniaui.net/tutorials/music-store-app/opening-a-dialog

可以从应用程序中的任何位置检索主窗口:

var mainWindow = Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop ? desktop.MainWindow : null;

然后,如果你希望跟上MVVM模式,你可以将这个显示对话框的实现移动到视图服务。

最新更新