绑定Loaded事件?

一旦我的MainWindow加载,我试图显示一个登录窗口,同时坚持MVVM模式。 所以我试图将我的主要Windows Loaded事件绑定到我的viewmodel中的事件。 这是我尝试过的:

MainWindowView.xaml

    

MainWindowViewModel.cs

 using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace ScrumManagementClient.ViewModel { class MainWindowViewModel : ViewModelBase { public void ShowLogInWindow(object sender, EventArgs e) { int i = 0; } } } 

我收到的错误消息是“Loaded =”{Binding ShowLogInWindow}“无效。”{Binding ShowLogInWindow}’不是有效的事件处理程序方法名称。只有生成的或代码隐藏类的实例方法才有效。“

您将不得不使用System.Windows.Interactivity dll。

然后在XAML中添加命名空间:

 xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 

然后你可以做的事情:

      

请注意,您必须使用ICommand (或者您使用Pract或DelegateCommand,如果您使用MVVMLight,则使用RelayCommand),并且Window的DataContext必须包含该ICommand。

使用附加行为。 这在MVVM中是允许的….

(下面的代码可能/可能不会像那样编译)

XAML ……

      

代码背后……

  class MainWindowViewModel : ViewModelBase { private ICommand _showLogInWindowCommand; public ICommand ShowLogInWindowCommand { get { if (_showLogInWindowCommand == null) { _showLogInWindowCommand = new DelegateCommand(OnLoaded) } return _showLogInWindowCommand; } } private void OnLoaded() { //// Put all your code here.... } } 

附加的行为……

  public static class MyAttachedBehaviors { public static DependencyProperty LoadedCommandProperty = DependencyProperty.RegisterAttached( "LoadedCommand", typeof(ICommand), typeof(MyAttachedBehaviors), new PropertyMetadata(null, OnLoadedCommandChanged)); private static void OnLoadedCommandChanged (DependencyObject depObj, DependencyPropertyChangedEventArgs e) { var frameworkElement = depObj as FrameworkElement; if (frameworkElement != null && e.NewValue is ICommand) { frameworkElement.Loaded += (o, args) => { (e.NewValue as ICommand).Execute(null); }; } } public static ICommand GetLoadedCommand(DependencyObject depObj) { return (ICommand)depObj.GetValue(LoadedCommandProperty); } public static void SetLoadedCommand( DependencyObject depObj, ICommand value) { depObj.SetValue(LoadedCommandProperty, value); } } 

DelegateCommand源代码可以在互联网上找到…它是最适合MVVM的ICommand API。

编辑:19.07.2016修复了两个小的语法错误

更新:

我发了一篇关于方法绑定的更灵活的新版本的post,它在这里使用了稍微不同的语法:

http://www.singulink.com/CodeIndex/post/updated-ultimate-wpf-event-method-binding

完整的代码清单可在此处获得:

https://gist.github.com/mikernet/7eb18408ffbcc149f1d9b89d9483fc19

任何未来的更新都将发布到博客,所以我建议在那里查看最新版本。

原答案:

.NET 4.5+现在支持事件的标记扩展。 我用它来创建一个方法绑定,可以像这样使用:

                    

查看模型方法签名:

 public void OpenFromFile(); public void Save(DocumentModel model); public void Edit(DocumentModel model); public void SetWebServiceState(bool state); public void SetCurrentElement(DesignerElementTypeA element); public void SetCurrentElement(DesignerElementTypeB element); public void SetCurrentElement(DesignerElementTypeC element); public void StartDrawing(MouseEventArgs e); public void AddDrawingPoint(MouseEventArgs e); public void EndDrawing(MouseEventArgs e); public class Document { // Fetches the document service for handling this document public DocumentService DocumentService { get; } } public class DocumentService { public void Save(Document document); } 

更多细节可以在这里找到: http : //www.singulink.com/CodeIndex/post/building-the-ultimate-wpf-event-method-binding-extension

完整的类代码可在此处获取: https : //gist.github.com/mikernet/4336eaa8ad71cb0f2e35d65ac8e8e161

在AttachedCommandBehavior V2又名ACB中提出了一种更通用的使用行为的方法,它甚至支持多个事件到命令的绑定,

这是一个非常基本的使用示例:

  

对于VS 2013 Update 5,我无法解决“无法将类型为’System.Reflection.RuntimeEventInfo’的对象强制转换为’System.Reflection.MethodInfo’。 而是在“核心”目录中,我做了一个简单的界面

 interface ILoad { void load(); } 

我的viewModel已经有了实现ILoad的load()函数。 在我的.xaml.cs中,我通过ILoad调用ViewModel load()。

 private void ml_Loaded(object sender, RoutedEventArgs e) { (this.ml.DataContext as Core.ILoad).load(); } 

除了POCO ILoad之外,xaml.cs对ViewModel一无所知,ViewModel对xaml.cs一无所知。 ml_loaded事件映射到ViewModel load()。