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

问题描述 投票:0回答:2

我有

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 的示例。

c# .net mvvm reactiveui avalonia
2个回答
1
投票

阅读有关交互的内容。基本上,您所做的就是在视图模型中创建交互,其中包括对话框的输入和输出。然后,在窗口后面的代码中,您可以向该交互注册一个处理程序,该处理程序负责打开对话框。请参阅此处:https://docs.avaloniaui.net/docs/0.10.x/tutorials/music-store-app/opening-a-dialog


0
投票

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

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

然后,如果您希望跟上 MVVM 模式,您可以将显示对话框的实现移至 视图服务

© www.soinside.com 2019 - 2024. All rights reserved.