3 回答
TA贡献1777条经验 获得超10个赞
一般来说:
你的 MVVM 视图模型应该只包含数据和命令。当然有很多例外,但请记住,基本上,它应该只包含与视图相关的命令和项目。
当事件处理程序应用于组件时,我看到了很多关于这一点的困惑。事情是; 当您在视图模型中放置 UI 组件的事件处理程序时,视图模型绑定到视图的实际实现(使用 UI 组件),而不是一般的“视图”。
根据经验; 你应该能够复制你的视图模型并在另一个实现中使用它,它应该只是编译。它不应该包含对 UI 元素本身的引用,或者通过事件处理等间接引用。
所以,是的,您应该将这些事件处理程序放在代码隐藏中,或者找到一个能够在视图/XAML 中处理它的框架或组件。从这样的事件中调用命令完全没问题。更实用的方法会说:将它们放在最有效的地方,并使您的代码最易读/易维护。如果你理解了 MVVM 的概念,你就会尽量减少这些混合模型的出现,这通常就足够了。
TA贡献1784条经验 获得超8个赞
我会用附加属性做这样的事情。例如,对于 FileDrop,我将实现一个附加属性,如下所示:
public static class WindowExtensions
{
public static readonly DependencyProperty ReadScriptFilesCommandProperty = DependencyProperty.RegisterAttached(
"ReadScriptFilesCommand",
typeof(ICommand),
typeof(WindowExtensions),
new PropertyMetadata(default(ICommand), OnReadScriptFilesCommandChanged));
private static void OnReadScriptFilesCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Window window = d as Window;
if (window == null)
return;
if (e.NewValue is ICommand)
{
window.Drop += WindowOnDrop;
}
if (e.OldValue != null)
{
window.Drop -= WindowOnDrop;
}
}
private static void WindowOnDrop(object sender, DragEventArgs e)
{
Window window = sender as Window;
if (window == null)
return;
if (e.Data.GetDataPresent(DataFormats.FileDrop))
{
string[] files = (string[])e.Data.GetData(DataFormats.FileDrop);
ICommand readScriptFilesCommand = GetReadScriptFilesCommand(window);
readScriptFilesCommand.Execute(files);
}
}
public static void SetReadScriptFilesCommand(DependencyObject element, ICommand value)
{
element.SetValue(ReadScriptFilesCommandProperty, value);
}
public static ICommand GetReadScriptFilesCommand(DependencyObject element)
{
return (ICommand)element.GetValue(ReadScriptFilesCommandProperty);
}
}
所以你可以在你Window的视图中设置它并将它链接到ICommand你的视图模型中。该命令采用string[]并执行逻辑。
- 3 回答
- 0 关注
- 146 浏览
添加回答
举报