绑定Loaded事件?

Eam*_*voy 11 c# data-binding wpf mvvm loaded

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

MainWindowView.xaml

 <Window x:Class="ScrumManagementClient.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525"
        DataContext="ViewModel.MainWindowViewModel"
        Loaded="{Binding ShowLogInWindow}">
    <Grid>

    </Grid>
 </Window>
Run Code Online (Sandbox Code Playgroud)

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;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

Lou*_*ann 28

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

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

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
Run Code Online (Sandbox Code Playgroud)

然后你可以做的事情:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding MyICommandThatShouldHandleLoaded}" />
    </i:EventTrigger>
</i:Interaction.Triggers>
Run Code Online (Sandbox Code Playgroud)

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

  • 小心.System.Windows.Interactivity不是.NET发行版的一部分. (9认同)
  • 你可以在网上合法地找到它,我相信它是 Blend 包的一部分 (3认同)
  • 您可以使用System.Windows.Interactivity NuGet包. (3认同)
  • @LouisKottmann:这仍然是最先进的吗?想知道 .NET 中是否有新的东西 (3认同)

WPF*_*-it 8

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

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

XAML ......

   <Window x:Class="..."
           ...
           xmlns:local="... namespace of the attached behavior class ..."
           local:MyAttachedBehaviors.LoadedCommand="{Binding ShowLogInWindowCommand}">
     <Grid>
     </Grid>
  </Window> 
Run Code Online (Sandbox Code Playgroud)

代码背后......

  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....
      }
  } 
Run Code Online (Sandbox Code Playgroud)

附加的行为......

  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);
      }
  }
Run Code Online (Sandbox Code Playgroud)

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

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

  • 我不认为互动是"经典"!由于各种点击一次以及它带来的重新部署问题,我不是互动的粉丝.我甚至观察到它对于深度控制模板来说有点不可靠.此外,我发现自定义附加行为的功能控制和所有权非常令人满意. (6认同)