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."
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With