【问题标题】:Win32 events + WPF + MVVMWin32 事件 + WPF + MVVM
【发布时间】:2014-05-20 21:23:40
【问题描述】:

SystemEvents.SessionSwitch += 新的 SessionSwitchEventHandler(SystemEvents_SessionSwitch);

我正在构建一个 wpf 应用程序,计算工作站锁定和解锁之间的时间 但是如果不放入主窗口代码隐藏,我很难实现它

我用来启动和停止计时器的代码

SystemEvents.SessionSwitch +=
                new SessionSwitchEventHandler(SystemEvents_SessionSwitch);
private static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
        {
            if (e.Reason == SessionSwitchReason.SessionLock)
            {
                //Start Timer
            }
            else if (e.Reason == SessionSwitchReason.SessionUnlock)
            {
                //Stop Timer -> show window
            }
        }

问题是,此事件驻留在 Microsoft.Win32 中 - 我似乎无法在 XAML 中引用它(如果我可以将它连接到 ICommand 代替)

你们所有的 MVVM 专家,我该怎么办? 我是否将其保留在主窗口代码隐藏中? 或者我可以在 XAML 中实际引用 Win32

还有一个附带问题... 计时器逻辑 - 我是否将其保存在单独的类中并将值存储在模型中? 不用说 - 我对 MVVM 还很陌生

【问题讨论】:

  • 就个人而言,我只是在视图模型的激活/停用中挂钩和取消挂钩事件(取自 Caliburn.Micro 的命名法)。那么在视图模型中这样做应该没有问题...
  • MVVM != 没有代码隐藏。 UI 逻辑在代码隐藏中。应用程序逻辑进入 VM。

标签: c# wpf xaml winapi mvvm


【解决方案1】:

MVVM 背后的核心原则是单元可测试性和责任分离。这通常是通过确保 ViewModel 不知道它上面的层(即“视图”)也不应该直接与任何特定于平台的类(即Microsoft.Win32.SystemEvents)交互来强制执行的。

我可能建议的一种方法是创建您自己的ISystemEvents 接口,该接口仅公开您希望 ViewModel 处理的事件。这个接口的实现可以被认为是你的“模型”层的一部分,并且基本上会包装来自Microsoft.Win32.SystemEvents的所需事件。您的应用程序会将“inject”接口作为 ViewModel 初始化的一部分。

public interface ISystemEvents
{
    event EventHandler<SessionSwitchEventArgs> SessionSwitch;
}

//Pass this implementation to your viewmodel, via the constructor
public class MySystemEvents : ISystemEvents
{
    public event EventHandler<SessionSwitchEventArgs> SessionSwitch
    {
        add { Microsoft.Win32.SystemEvents.SessionSwitch += value; }
        remove { Microsoft.Win32.SystemEvents.SessionSwitch -= value; }
    }
}

public class MyViewModel
{
    public MyViewModel(ISystemEvents systemEvents)
    {
        //Store the instance of your object here, and subscribe to the desired events
    }
}

【讨论】:

  • 我认为 mvvm 指南告诉我们模型不应该包含特定用法的知识(我猜这是? - 还是我弄错了) - 虽然我确实喜欢你的回答 :)
  • 我添加了一个非常简短的 ISystemEvents 接口实现示例:MySystemEvents。我认为您在这里将“模型”与“视图模型”混淆了。 ViewModel 应该尽可能地编程到一个接口而不是一个具体的模型。这允许您通过提供自己的“测试”模型来进行单元测试,或者在生产中使用“真实”模型。在此示例中,“MySystemEvents”将是生产模型 - 您可以创建一个假的 ISystemEvents 来测试您的 ViewModel 在开发过程中如何对其做出反应。
猜你喜欢
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-04
  • 2019-08-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多