Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding the Loaded event?

I am trying to display a login window once my MainWindow loads while sticking to the MVVM pattern. So I am trying to Bind my main windows Loaded event to an event in my viewmodel. Here is what I have tried:

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>

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;
        }
    }
}

The error message I am getting is "Loaded="{Binding ShowLogInWindow}" is not valid. '{Binding ShowLogInWindow}' is not a valid event handler method name. Only instance methods on the generated or code-behind class are valid."

like image 367
Eamonn McEvoy Avatar asked Oct 25 '11 10:10

Eamonn McEvoy


2 Answers

You're going to have to use the System.Windows.Interactivity dll.

Then add the namespace in your XAML:

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

Then you can do stuff like:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding MyICommandThatShouldHandleLoaded}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

Please note that you will have to use an ICommand (or DelegateCommand is you use Prism, or RelayCommand if you use MVVMLight), and the DataContext of your Window must hold that ICommand.

like image 105
Louis Kottmann Avatar answered Oct 01 '22 20:10

Louis Kottmann


Use Attached Behavior. That is allowed in MVVM ....

(code below may / may not compile just like that)

XAML ...

   <Window x:Class="..."
           ...
           xmlns:local="... namespace of the attached behavior class ..."
           local:MyAttachedBehaviors.LoadedCommand="{Binding ShowLogInWindowCommand}">
     <Grid>
     </Grid>
  </Window> 

Code Behind...

  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....
      }
  } 

And the attached behavior...

  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 source code can be found on the internet... Its the most suited ICommand API available for MVVM.

edit:19.07.2016 two minor syntax errors fixed

like image 33
WPF-it Avatar answered Oct 01 '22 19:10

WPF-it