在 Wpf Core 应用程序中使用 MvvmCross 的 OpenFileDialog
OpenFileDialog using MvvmCross in a Wpf Core application
我最近开始了一个小项目来更新我所获得的一点点 wpf 知识并尝试新的东西。我对 MvvmCross 很感兴趣,但我想暂时保持它的小。我的目标是一个简单的图像操纵器;图像到 ascii、重新着色等等...
我的设置: Mvx 核心库(.NET Standard 2.0)
- MainViewModel - 有方法 OpenFileDialog_Clicked 被输入到 openFileDialogCommand
Wpf 应用程序 (.NET Core 3.1)
- MainView - 有一个带有按钮的菜单,该按钮绑定到 MainViewModel 上的 openFileDialogCommand
墙我运行变成了:
尝试获取 OpenFileDialog(命名空间:Microsoft.Win32)来执行此操作:
public void OpenFile_Clicked()
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
Nullable<bool> result = dlg.ShowDialog();
if(result) {
// big cash prize
}
}
我指定了命名空间,因为我发现有几篇文章讨论了 OpenFileDialog 上缺少引用。在我的例子中,awnser 是 .NET Standard。那里根本不存在 OpenFileDialog,这正是我的问题。当核心库必须是 .NET Standard 类型时,我应该如何在我的 ViewModel 中调用 OpenFileDialog?对 wpf 项目的依赖不会破坏整个 mvvm 模式吗?!
老实说:我已经阅读了整个 mvx 文档并找到了一些线索,但我的 wpf/mvvm/xaml 理解可能延伸到其中的三分之一。 MvvmCross Inversion of Control 文档看起来对我很有用,但我仍然不明白这在我的案例中是如何工作的。给定的示例 https://www.mvvmcross.com/documentation/fundamentals/inversion-of-control-ioc?scroll=43 没有显示这些接口的位置,对我来说,这一切都归结为我需要以某种方式将 OpenFileDialog 从 wpf 项目中移出到核心项目中。
"@BionicCode excuse my french but what are you talking about? "The
click handler should be in the code-behind of the view"? I think you
had a little switcheroo there. My MainViewModel has the method and
command while my MainView binds to it. I think I did everything
exactly right. edit: I also clarified that i did NOT intend to make my
core dependant on the wpf project."
没问题。我想因为你是法国人,所以你完全误解了我。
我又来了:看来你用的是MVVM模式
要正确实现 MVVM,您必须遵循一些规则(模式)。
一条规则是不要将视图组件的职责与视图模型组件的职责混在一起。
根据定义,视图组件仅向用户显示数据并处理用户输入,例如收集数据或与用户交互。
用户输入始终是用户界面的一部分 (UI)。对话框是旨在与用户交互的控件(应用程序界面)。在您的情况下,对话框收集用户输入(文件路径)。
这就是为什么这个逻辑属于视图 => 而不是在 MainViewModel
中使用 OpenFile_Clicked
只是为了向用户显示 OpenFileDialog
,OpenFile_Clicked
应该是UI 的 code-behind 例如,MainWindow.xaml.cs
.
此事件处理程序显示对话框并将结果(选择的文件路径)传递给 MainViewModel
(使用数据绑定、命令模式或通过直接引用)。
"Wouldn't a dependency on the wpf project ruin the entire mvvm
pattern?!"
不,不是对 WPF 项目的引用会破坏 MVVM 模式,而是对 OpenFileDialog
class.
的引用
如果您遵循前面解释的原则并从您的 MainViewModel
中删除对 OpenFileDialog
的依赖,您将取回 MVVM 的优势。
换句话说:根本不要在 MainViewModel
中使用 OpenFileDialog
或任何其他视图组件。
"How am I supposed to call OpenFileDialog
in my ViewModel when the
Core library has to be of type .NET Standard?"
再说一次:根本不要在 MainViewModel
中使用 OpenFileDialog
或任何其他视图组件:
MainWindow.xaml.cs(WPF .NET Core 程序集)
partial class MainWindow
{
// Event handler for Button.Click
private void OnOpenDialogButton_Click(object sender, EventArgs e)
{
var dialog = new System.Windows.Forms.OpenFileDialog();
dialog.Show();
string selectedFilePath = dialog.FileName;
this.ViewModel.HandleSelectedFile(selectedFilePath);
}
}
MainViewModel.cs(.NET 标准库程序集)
public void HandleSelectedFile(string filePath)
{
// TODO::Handle file e.g. open and read
}
使用 OpenFileDialog
强制引用程序集放弃 .NET 标准合规性。因为 OpenFileDialog
是 System.Windows.Forms
中定义的 class,引用程序集需要使用 .NET Framework 或 .NET Core 库。
按照上面的示例将从 MainViewModel
中删除此依赖项并使您的库再次符合 .NET 标准。
"The MvvmCross Inversion of Control documentation looked useful to me
but I still don't get how this would work in my case."
控制反转解决了一个不同的问题,与 MVVM 或显示视图模型中的对话框无关(不要这样做)。它使应用程序可以通过交换部件进行扩展。
由于您使用的是 .NET Core,因此您可以使用 IoC 容器中的构建:Overview of dependency injection
我最近开始了一个小项目来更新我所获得的一点点 wpf 知识并尝试新的东西。我对 MvvmCross 很感兴趣,但我想暂时保持它的小。我的目标是一个简单的图像操纵器;图像到 ascii、重新着色等等...
我的设置: Mvx 核心库(.NET Standard 2.0)
- MainViewModel - 有方法 OpenFileDialog_Clicked 被输入到 openFileDialogCommand
Wpf 应用程序 (.NET Core 3.1)
- MainView - 有一个带有按钮的菜单,该按钮绑定到 MainViewModel 上的 openFileDialogCommand
墙我运行变成了: 尝试获取 OpenFileDialog(命名空间:Microsoft.Win32)来执行此操作:
public void OpenFile_Clicked()
{
Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog();
Nullable<bool> result = dlg.ShowDialog();
if(result) {
// big cash prize
}
}
我指定了命名空间,因为我发现有几篇文章讨论了 OpenFileDialog 上缺少引用。在我的例子中,awnser 是 .NET Standard。那里根本不存在 OpenFileDialog,这正是我的问题。当核心库必须是 .NET Standard 类型时,我应该如何在我的 ViewModel 中调用 OpenFileDialog?对 wpf 项目的依赖不会破坏整个 mvvm 模式吗?! 老实说:我已经阅读了整个 mvx 文档并找到了一些线索,但我的 wpf/mvvm/xaml 理解可能延伸到其中的三分之一。 MvvmCross Inversion of Control 文档看起来对我很有用,但我仍然不明白这在我的案例中是如何工作的。给定的示例 https://www.mvvmcross.com/documentation/fundamentals/inversion-of-control-ioc?scroll=43 没有显示这些接口的位置,对我来说,这一切都归结为我需要以某种方式将 OpenFileDialog 从 wpf 项目中移出到核心项目中。
"@BionicCode excuse my french but what are you talking about? "The click handler should be in the code-behind of the view"? I think you had a little switcheroo there. My MainViewModel has the method and command while my MainView binds to it. I think I did everything exactly right. edit: I also clarified that i did NOT intend to make my core dependant on the wpf project."
没问题。我想因为你是法国人,所以你完全误解了我。
我又来了:看来你用的是MVVM模式
要正确实现 MVVM,您必须遵循一些规则(模式)。
一条规则是不要将视图组件的职责与视图模型组件的职责混在一起。
根据定义,视图组件仅向用户显示数据并处理用户输入,例如收集数据或与用户交互。
用户输入始终是用户界面的一部分 (UI)。对话框是旨在与用户交互的控件(应用程序界面)。在您的情况下,对话框收集用户输入(文件路径)。
这就是为什么这个逻辑属于视图 => 而不是在 MainViewModel
中使用 OpenFile_Clicked
只是为了向用户显示 OpenFileDialog
,OpenFile_Clicked
应该是UI 的 code-behind 例如,MainWindow.xaml.cs
.
此事件处理程序显示对话框并将结果(选择的文件路径)传递给 MainViewModel
(使用数据绑定、命令模式或通过直接引用)。
"Wouldn't a dependency on the wpf project ruin the entire mvvm pattern?!"
不,不是对 WPF 项目的引用会破坏 MVVM 模式,而是对 OpenFileDialog
class.
的引用
如果您遵循前面解释的原则并从您的 MainViewModel
中删除对 OpenFileDialog
的依赖,您将取回 MVVM 的优势。
换句话说:根本不要在 MainViewModel
中使用 OpenFileDialog
或任何其他视图组件。
"How am I supposed to call
OpenFileDialog
in my ViewModel when the Core library has to be of type .NET Standard?"
再说一次:根本不要在 MainViewModel
中使用 OpenFileDialog
或任何其他视图组件:
MainWindow.xaml.cs(WPF .NET Core 程序集)
partial class MainWindow
{
// Event handler for Button.Click
private void OnOpenDialogButton_Click(object sender, EventArgs e)
{
var dialog = new System.Windows.Forms.OpenFileDialog();
dialog.Show();
string selectedFilePath = dialog.FileName;
this.ViewModel.HandleSelectedFile(selectedFilePath);
}
}
MainViewModel.cs(.NET 标准库程序集)
public void HandleSelectedFile(string filePath)
{
// TODO::Handle file e.g. open and read
}
使用 OpenFileDialog
强制引用程序集放弃 .NET 标准合规性。因为 OpenFileDialog
是 System.Windows.Forms
中定义的 class,引用程序集需要使用 .NET Framework 或 .NET Core 库。
按照上面的示例将从 MainViewModel
中删除此依赖项并使您的库再次符合 .NET 标准。
"The MvvmCross Inversion of Control documentation looked useful to me but I still don't get how this would work in my case."
控制反转解决了一个不同的问题,与 MVVM 或显示视图模型中的对话框无关(不要这样做)。它使应用程序可以通过交换部件进行扩展。
由于您使用的是 .NET Core,因此您可以使用 IoC 容器中的构建:Overview of dependency injection