绑定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()。