繁体   English   中英

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

[英]Show dialog from ViewModel in ReactiveUI Avalonia (MVVM)

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

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

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM