gpt4 book ai didi

MVVM 之外的 WPF 命令用法

转载 作者:行者123 更新时间:2023-12-03 10:55:11 27 4
gpt4 key购买 nike

我一直在尝试使用 WPF 学习正确的 MVVM 用法。我基本上明白了,但我在使用命令的特定问题上有点卡住了。我知道一个命令允许我执行可以由多个 UI 元素触发的相同操作,但是我看到的所有示例都具有在 View 模型或 View 中定义的命令。

当操作范围超出 View 模型时,您如何使用命令?例如,也许我想定义一个关闭应用程序的命令。这将允许按钮和菜单项都触发关闭,但如果关闭应用程序还需要其他操作,例如关闭数据库连接和写入文件,该怎么办?这些类型的任务通常发生在模型或 View 之外的某个地方。

在这种情况下,我是否只是将 UI 元素连接到事件?我是否在 View 模型中声明事件并让命令触发事件?

最佳答案

I've been trying to learn proper MVVM usage with WPF.



在实践中,MVVM 可以用一句话来概括: View 模型负责提供其 View 所需的所有数据和功能。

How do you use commands when the scope of action goes further than the view model?



在 MVVM 中,每个 View 都有一个 View 模型,所以没有比 View 模型更进一步的了。处理使用 ICommand 的好方法WPF 中的 s 是利用 delegate 之一基于 Command可用,如流行的 RelayCommand .您可以在 WPF Apps With The Model-View-ViewModel Design Pattern 中找到详细信息。 MSDN 上的页面。

在 UI 中,它们的使用方式与任何其他 ICommand 相同。 ,但在 View 模型中,您可以只使用方法甚至内联 delegate s 处理 ICommand.ExecuteICommand.CanExecute方法。我使用我自己的 RelayCommand 版本对于你的场景,我会做这样的事情:
public ICommand CloseCommand
{
get
{
return new ActionCommand(action => Close(null), canExecute => CanClose(null));
}
}

private void Close(object commandParameter)
{
if (SomeDataItem.HasChanges)
{
if (WindowManager.AskUserIfTheyWantToSave(SomeDataItem))
DataProvider.Save(SomeDataItem);
}
HardDriveManager.SaveSettings();
WindowManager.CloseMainWindow();
}

现在很明显,你没有我的 ...Manager类,但你如何保存这个和那个并不重要......这只是向你展示什么是可能的。

what if closing the application also requires other actions, such as closing a database connection?



现代数据库技术实际上并不需要您在任何时候手动关闭数据库连接。

在这一点上,我想明确一点,在使用 MVVM 时,在 UserControl 后面的代码中处理事件是完全可以接受的。 s,甚至是 MainWindow .所以在 MainWindow.xaml.cs中保存设置绝对没有问题像这样:
Loaded += MainWindow_Loaded;
Closing += MainWindow_Closing;

...
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
Settings.Default.Reload();
WindowStartupLocation = WindowStartupLocation.Manual;
Left = Settings.Default.ApplicationLocation.X;
Top = Settings.Default.ApplicationLocation.Y;
Width = Settings.Default.ApplicationSize.Width;
Height = Settings.Default.ApplicationSize.Height;
WindowState = Settings.Default.IsApplicationMaximised ? WindowState.Maximized : WindowState.Normal;
}

private void MainWindow_Closing(object sender, EventArgs e)
{
Settings.Default.ApplicationLocation = new Point(Left, Top);
Settings.Default.ApplicationSize = new Size(Width, Height);
Settings.Default.IsApplicationMaximised = WindowState == WindowState.Maximized;
Settings.Default.Save();
}

Do I declare an event in the viewmodel and have the command trigger the event?



事件是 UI 对象,永远不应该在 View 模型中看到......我们不希望在 View 模型项目引用中出现任何与 UI 相关的 dll。当你真的需要处理一个事件时,你可以在后面的代码中处理它,记住你可以从后面的 View 代码中访问数据绑定(bind) View 模型,如下所示:
SomeViewModel viewModel = (SomeViewModel)DataContext;

或者更好的是,在附加属性中处理事件,您可以在 XAML 中简单地附加该事件。我建议您不要扩展这个相当长的答案来解释如何做到这一点,而是在线搜索,因为有很多例子。哦,实际上,我只记得我在 What's the best way to pass event to ViewModel? 中向某人解释了如何执行此操作在 Stack Overflow 上发帖。

所以这比我预期的持续时间更长,但希望它回答了你的(一些)问题。

关于MVVM 之外的 WPF 命令用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22414816/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com