我有
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/docs/0.10.x/tutorials/music-store-app/opening-a-dialog
可以从应用程序中的任何位置检索主窗口:
var mainWindow = Application.Current?.ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop ? desktop.MainWindow : null;
然后,如果您希望跟上 MVVM 模式,您可以将显示对话框的实现移至 视图服务。