i have this in MainWindow.xaml
<Window.InputBindings>
<KeyBinding Modifiers="Ctrl" Key="Delete" Command="{Binding DelAllMessages}"/>
</Window.InputBindings>
and in MainViewModel
public void DelAllMessages()
{
MessageBoxResult result = MessageBox.Show(
"Are you sure you want to delete?",
"Confirmation",
MessageBoxButton.YesNo,
MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
// todo
}
}
}
when i press ctrl+del in keyboard in window then this method does not hit.what is missing?
You need to use Commands instead of directly binding the method. One think to keep in mind is in order to have a communication between View model and View is via Properties.
Step 1:-
Create a Command Handler class and Implement ICommand as shown in the below code.
public class CommandHandler : ICommand
{
private Action<object> _action;
private bool _canExeute;
public event EventHandler CanExecuteChanged;
private bool canExeute
{
set
{
_canExeute = value;
CanExecuteChanged(this, new EventArgs());
}
}
public CommandHandler(Action<object> action, bool canExecute)
{
_action = action;
_canExeute = canExecute;
}
public bool CanExecute(object parameter)
{
return _canExeute;
}
public void Execute(object parameter)
{
_action(parameter);
}
}
Step 2:-
Use the newly created class of Command in your Window's code behind.
Create a property of ICommand and provide your DelAllMessages() as your action to that Command, so when there is Clt + Del Pressed, it calls your method.
private ICommand _KeyCommand;
public ICommand KeyCommand
{
get { return _KeyCommand ?? (_KeyCommand = new CommandHandler(obj => DelAllMessages(), true)); }
}
Step 3:-
Assign your your window class as DataContext to the windows' Xaml.
this.DataContext = this;
Check out whole class Code.
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
private ICommand _KeyCommand;
public ICommand KeyCommand
{
get { return _KeyCommand ?? (_KeyCommand = new CommandHandler(obj => DelAllMessages(), true)); }
}
public void DelAllMessages()
{
MessageBoxResult result = MessageBox.Show(
"Are you sure you want to delete?",
"Confirmation",
MessageBoxButton.YesNo,
MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
// todo
}
}
}
Step 4:-
Bind the newly created Command property in Xaml.
<Window.InputBindings>
<KeyBinding Modifiers="Ctrl" Key="Delete" Command="{Binding KeyCommand}"/>
</Window.InputBindings>
Whole Xaml Code:-
<Window x:Class="WpfApp4.TriggerTest"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp4"
mc:Ignorable="d"
Title="Window1" Height="450" Width="800">
<Window.InputBindings>
<KeyBinding Modifiers="Ctrl" Key="Delete" Command="{Binding KeyCommand}"/>
</Window.InputBindings>
<Grid>
</Grid>
</Window>
Related
I created a WPF sample (using caliburn micro with MVVM pattern, no code-behind) with a view model and their related views:
ShellView.xaml and ShellViewModel.cs
The ShellView contains:
A ComobBox, which contains a list of string, if this combox selection is changed, it will raise comboBox1_SelectionChanged() in ShellViewModel.
A Button, if click this button, it will raise Button1_Click() to delete the first item of list in ShellViewModel.
My questions:
If I want to click the button without trigger comboBox1_SelectionChanged in view model, how to do that?
If it implemented in code-behind, I can do like this:
public void Button1_Click(object sender, EventArgs e)
{
comboBox1.SelectionChanged -= comboBox1_SelectionChanged;
MyCollection.RemoveAt(0);
comboBox1.SelectionChanged += comboBox1_SelectionChanged;
}
I have no idea how to achieve this in view model. The following is the code:
ShellView.xaml
<UserControl x:Class="WpfApp.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp.Views"
xmlns:cal="http://caliburnmicro.com"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=" auto"/>
<RowDefinition Height=" auto"/>
</Grid.RowDefinitions>
<ComboBox Name="comboBox1" Grid.Row="0" ItemsSource="{Binding MyCollection}" SelectedValue="{Binding SelectMyListValue}"
cal:Message.Attach="[Event SelectionChanged]=[Action comboBox1_SelectionChanged($source,$eventArgs)]" />
<Button Name="Button1" Grid.Row="1" Content="Delete"
cal:Message.Attach="[Event Click]=[Action Button1_Click($source,$eventArgs)]" />
</Grid>
</UserControl>
ShellViewModel.cs
using Caliburn.Micro;
using System;
using System.Windows.Controls;
namespace WpfApp.ViewModels
{
public class ShellViewModel : Conductor<object>.Collection.OneActive
{
private BindableCollection<string> _myCollection = new BindableCollection<string>() { "item1", "item2"};
public BindableCollection<string> MyCollection
{
get => _myCollection;
set
{
_myCollection = value;
NotifyOfPropertyChange(() => MyCollection);
}
}
private string _selectMyListValue = "item1";
public string SelectMyListValue
{
get => _selectMyListValue;
set
{
_selectMyListValue = value;
NotifyOfPropertyChange(nameof(SelectMyListValue));
}
}
public void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Do something...
}
public void Button1_Click(object sender, EventArgs e)
{
MyCollection.RemoveAt(0);
}
}
}
Thank you in advance.
Your requirement can't be fully met, as when you remove the selected item from the collection a change of SelectedValue (to null) is inevitable.
Furthermore: You don't need to bind to the SelectionChanged event. You already have a binding to SelectedValue, so the setter of the bound property is called when the selection changes. This doesn't happen, when you remove a value from the collection that is not currently selected.
I would also recommend not to subscribe to the Clicked event of the button, but to bind an ICommand (added to your viewmodel) to the Command property of the button. An easy to use implementation would be the RelayCommand from the Windows Community Toolkit. You can read about it here: https://learn.microsoft.com/en-us/windows/communitytoolkit/mvvm/relaycommand. It also isn't difficult to implemnt a version on your own, if you don't want to use the whole toolkit.
Code sample:
public class RelayCommand : ICommand
{
private readonly Action<object?> execute;
private readonly Func<object?, bool> canExecute;
public RelayCommand(
Action<object?> execute,
Func<object?, bool>? canExecute = null)
{
this.execute = execute;
this.canExecute = canExecute ?? (_ => true);
}
public bool CanExecute(object? parameter) => this.canExecute(parameter);
public void Execute(object? parameter)
{
this.execute(parameter);
}
public event EventHandler? CanExecuteChanged;
}
// on your viewmodel add...
public ICommand RemoveFirstItemCommand { get; set; }
private void RemoveFirstItem(object? param)
{
if (this.Items.Count > 0)
{
this.Items.RemoveAt(0);
}
}
// ...and in the constructor init the command
this.RemoveFirstItemCommand = new RelayCommand(this.RemoveFirstItem);
I got a solution which achieved the goal, but I'm not sure if it's the right way.
There is a "Microsoft.Xaml.Behaviors" which provided "Interaction.Triggers" that contains "ComparisonCondition". I can use it to bind a value to determine the EventCommand is raised or not.
I updated the code as following:
ShellViewModel.cs
using Caliburn.Micro;
using System;
using System.Windows.Controls;
using WpfApp.Commands;
namespace WpfApp.ViewModels
{
public class ShellViewModel : Conductor<object>.Collection.OneActive
{
private bool _IsEnableSelectionChangedCommand = true;
public bool IsEnableSelectionChangedCommand
{
get => _IsEnableSelectionChangedCommand;
set
{
_IsEnableSelectionChangedCommand = value;
NotifyOfPropertyChange(() => IsEnableSelectionChangedCommand);
}
}
private BindableCollection<string> _myCollection = new BindableCollection<string>() { "item1", "item2"};
public BindableCollection<string> MyCollection
{
get => _myCollection;
set
{
_myCollection = value;
NotifyOfPropertyChange(() => MyCollection);
}
}
private string _selectMyListValue = "item1";
public DelegateCommand<object> DoSelectionChangedCommand { get; }
public ShellViewModel()
{
DoSelectionChangedCommand = new DelegateCommand<object>(comboBox1_SelectionChanged, CanExecute);
}
private bool CanExecute(object param)
{
return true;
}
private void comboBox1_SelectionChanged(object param)
{
SelectionChangedEventArgs e = param as SelectionChangedEventArgs;
ComboBox item = e.Source as ComboBox;
// Do something...
}
public string SelectMyListValue
{
get => _selectMyListValue;
set
{
_selectMyListValue = value;
NotifyOfPropertyChange(nameof(SelectMyListValue));
}
}
public void Button1_Click(object sender, EventArgs e)
{
IsEnableSelectionChangedCommand = false;
MyCollection.RemoveAt(0);
IsEnableSelectionChangedCommand = true;
}
}
}
ShellView.xaml
<UserControl x:Class="WpfApp.Views.ShellView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:cal="http://caliburnmicro.com"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:cmd="clr-namespace:WpfApp.Commands"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height=" auto"/>
<RowDefinition Height=" auto"/>
</Grid.RowDefinitions>
<ComboBox Name="comboBox1" Grid.Row="0" ItemsSource="{Binding MyCollection}" SelectedValue="{Binding SelectMyListValue}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventCommand Command="{Binding DoSelectionChangedCommand}" />
<i:Interaction.Behaviors>
<i:ConditionBehavior>
<i:ConditionalExpression>
<i:ComparisonCondition LeftOperand= "{Binding IsEnableSelectionChangedCommand}" Operator="Equal" RightOperand="True"/>
</i:ConditionalExpression>
</i:ConditionBehavior>
</i:Interaction.Behaviors>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
<Button Name="Button1" Grid.Row="1" Content="Delete"
cal:Message.Attach="[Event Click]=[Action Button1_Click($source,$eventArgs)]" />
</Grid>
</UserControl>
I currently have working code which is implemented in MainWindow.xaml.cs that I am trying to move to a class which is giving me an error that my UI label does not exist in the current context.
Here is the code that works in the MainWindow:
public partial class MainWindow : Window
{
......
private RX consumer = new RX();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
Task backgroundDBTask = Task.Factory.StartNew(() => { Consumer(consumer);}, TaskCreationOptions.LongRunning);
}
}
public void Consumer(Consumer consumer)
{
while (true)
{
Thread.Sleep(1000);
.......
Dispatcher.BeginInvoke(new Action(() =>
{
mylbl.Content = value.ToString();
}), DispatcherPriority.Background);
}
}
Then I tried moving the code to a separate class:
public partial class MainWindow : Window
{
....
private RX consumer = new RX();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
Task backgroundDBTask = Task.Factory.StartNew(() => { consumer.ProcessMessages(); }, TaskCreationOptions.LongRunning);
}
}
}
public class RX
{
public void ProcessMessages()
{
while (true)
{
Thread.Sleep(1000);
....
var m_dispatcher = Application.Current.MainWindow;
m_dispatcher.Dispatcher.BeginInvoke(new Action(() =>
{
mylbl.Content = value.ToString();
}), DispatcherPriority.Background);
}
}
}
I'm getting the error on:
mylbl.Content = value.ToString();
from the class RX. I tried this as recommended var m_dispatcher = Application.Current.MainWindow to get to the MainWindow thread but its still giving an error.
You cannot access mylbl from other classes , other than MyWindow since it is defined there .
You can implement MVVM and bind the content property to string in view model and update the content .
or segregate your business logic to separate class and expose this to MyWindow.Xaml.cs.
You can have a public method which returns "value" in RX . and you can update your content in MyWindow.xaml.cs by accessing this method
or pass Label instance to ProcessMessage method and update the content. Of course,add a reference System.Windows.Controls in your class.
However this is not a good design . I suggest you to go through MVVM.
public void ProcessMessages(Label mylbl)
{
while (true)
{
Thread.Sleep(1000);
....
var m_dispatcher = Application.Current.MainWindow;
m_dispatcher.Dispatcher.BeginInvoke(new Action(() =>
{
mylbl.Content = value.ToString();
}), DispatcherPriority.Background);
}
}
and caller will look like this
public partial class MainWindow : Window
{
....
private RX consumer = new RX();
private void Window_Loaded(object sender, RoutedEventArgs e)
{
try
{
Task backgroundDBTask = Task.Factory.StartNew(() => { consumer.ProcessMessages(mylbl); }, TaskCreationOptions.LongRunning);
}
}
}
As suggested by Clemens , i am updating solution in MVVM way.
XAML Part:
<Window x:Class="MvvmExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MvvmExample"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid >
<Label Content="{Binding LableContent}" Height="100" Width="500" Foreground="Red"/>
</Grid>
</Window>
I am binding LableContent string property to Content property of Label. And setting data content at the top to my View Model. Also,to bind event to command i have used interactivity dll.
ViewModel will look like this.
public class ViewModel : INotifyPropertyChanged
{
#region Constants and Enums
#endregion
#region Private and Protected Member Variables
private string _lableContent;
#endregion
#region Private and Protected Methods
private void OnLoaded(object obj)
{
Task.Factory.StartNew(() => { ProcessMessages(); }, TaskCreationOptions.LongRunning);
}
private void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
#region Constructors
public ViewModel()
{
LoadedCommand = new RelayCommand(OnLoaded);
}
#endregion
#region Public Properties
public event PropertyChangedEventHandler PropertyChanged;
public string LableContent
{
get
{
return _lableContent;
}
set
{
_lableContent = value;
OnPropertyChanged(nameof(LableContent));
}
}
public ICommand LoadedCommand { get; }
#endregion
#region Public Methods
public void ProcessMessages()
{
while (true)
{
Thread.Sleep(1000);
LableContent = "your value field";
}
}
#endregion
}
I have used ICommand implementation for commands .
Also i have used INotifyPropertyChanged for binding .
I assume you have the knowledge about following topics , If not there are plenty of help available in stack overflow on these
INotifyProertyChanged
Event to command binding
What is data context and how to set the data context
what is ICommand and implementing ICommand
I'm new to Prism and I'm trying to update a text in MainWindow.xaml another view in region.
MainWindowViewModel
private string _message = "Prism";
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value);}
}
MainWindow.xaml
<Window x:Class="XXXX.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
Title="{Binding Title}">
<Grid>
<StackPanel>
<TextBlock Text="{Binding Message, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="48"></TextBlock>
<ContentControl prism:RegionManager.RegionName="ViewARegion" />
</StackPanel>
</Grid>
ViewAViewModel
public ICommand ClickCommand
{
get;
private set;
}
public ViewAViewModel()
{
ClickCommand = new DelegateCommand(ClickedMethod);
}
private void ClickedMethod()
{
MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
mainWindowViewModel.Message = "Prism View A";
}
ViewA.xaml
<UserControl x:Class="XXXX.Views.ViewA"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:XXXX.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d">
<Grid>
<StackPanel>
<Button Content="Click"
Command="{Binding ClickCommand}">
</Button>
</StackPanel>
</Grid>
Now when I click the button it's working correctly I mean it's setting the Message property in MainWindowViewModel but it's not udating the View in MainWindow.xaml.
What should I do to get this working as I'm expecting to update the view on button click?
MainWindowViewModel mainWindowViewModel = new MainWindowViewModel();
mainWindowViewModel.Message = "Prism View A";
This creates a new instance of MainWindowViewModel that has nothing to do with the instance that's bound to your MainWindow. You can change properties on this new instance all day long, the real view model will not care.
You have to implement some view model to view model communication mechanism, e.g. use IEventAggregator or a shared service, so that the information ("click happened" or "message changed" or whatever) can be passed from ViewA to the MainWindow.
You could use the event aggregator to send an event from ViewAViewModel to MainWindowViewModel:
public class ViewAViewModel
{
private readonly IEventAggregator _eventAggregator;
public ViewAViewModel(IEventAggregator eventAggregator)
{
_eventAggregator = eventAggregator;
ClickCommand = new DelegateCommand(ClickedMethod);
}
public ICommand ClickCommand
{
get;
private set;
}
private void ClickedMethod()
{
_eventAggregator.GetEvent<PubSubEvent<string>>().Publish("Prism View A");
}
}
public class MainWindowViewModel : BindableBase
{
public MainWindowViewModel(IEventAggregator eventAggregator)
{
eventAggregator.GetEvent<MessageSentEvent>().Subscribe(MessageReceived);
}
private void MessageReceived(string message)
{
Message = message;
}
private string _message = "Prism";
public string Message
{
get { return _message; }
set { SetProperty(ref _message, value); }
}
}
There is a complete example available on GitHub: https://github.com/PrismLibrary/Prism-Samples-Wpf/tree/master/14-UsingEventAggregator
I have built a dummy UserControl that has a method in its code-behind to display a message. I have used this control in my main window and want to execute its method when I click a Button using Commands and MVVM. Is this a good design, and if not, how can I improve it? My current code looks like this:
<UserControl x:Class="ControlBining.Control1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid DataContext="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}">
</Grid>
</UserControl>
public partial class Control1 : UserControl
{
public Control1()
{
InitializeComponent();
}
public void ShowMessage()
{
MessageBox.Show("Called from other control!");
}
}
<Window x:Class="ControlBining.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ControlBining"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
<local:ViewModel/>
</Window.DataContext>
<StackPanel Margin="0 50 0 0">
<local:Control1 Width="100"/>
<Button Width="100" Content="Show Message"/>
</StackPanel>
</Window>
public class RelayCommand : ICommand
{
private readonly Predicate<object> m_canExecute;
private readonly Action<object> m_execute;
public RelayCommand(Predicate<object> canExecute, Action<object> execute)
{
m_canExecute = canExecute;
m_execute = execute;
}
public event EventHandler CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public bool CanExecute(object parameter)
{
return m_canExecute(parameter);
}
public void Execute(object parameter)
{
m_execute(parameter);
}
}
Currently, I have made it work using the following code, but I am not sure if this is a good design:
private void Control1_Loaded(object sender, RoutedEventArgs e)
{
ViewModel m = (ViewModel)DataContext;
m.ShowMessage += M_ShowMessage;
}
private void M_ShowMessage()
{
ShowMessage();
}
public event Action ShowMessage;
private ICommand m_showMessageCommand;
public ICommand ShowMessageCommand
{
get
{
return m_showMessageCommand ?? (m_showMessageCommand = new RelayCommand(
p => true,
p => ShowMessage?.Invoke()));
}
}
If you simply need to show a message, you should move the ShowMessage() method to the view model and use a message service to do this from the view model class.
If you really want to call some method that it only makes sense to define in the view, this can be done by implementing an interface in the view and inject the view model with this interface. For example when you invoke the command:
public interface IView
{
void ShowMessage();
}
public partial class Control1 : UserControl, IView
{
public Control1()
{
InitializeComponent();
}
public void ShowMessage()
{
MessageBox.Show("Called from other control!");
}
}
View Model:
public ICommand ShowMessageCommand
{
get
{
return m_showMessageCommand ?? (m_showMessageCommand = new RelayCommand(
p => true,
p =>
{
IView view as IView;
if (view != null)
{
//...
view.ShowMessage();
}
}));
}
}
The view model knows nothing about the view, it only knows about an interface which of course may be called something else than IView.
The other option is to use an event aggregator or a messenger to send an event or a message from the view model to the view in a lously coupled way. Please refer to this blog post for more information about this.
Neither approach break the MVVM pattern.
I want to bind the loaded event from my view so tha i can read some settings at the start. With some searching i made this but it does not work. what am i missing?
the view:
<UserControl x:Name="UserControlRegistratie" x:Class="Qbox_0001.Views.RegistratieView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d" HorizontalContentAlignment="Left" VerticalContentAlignment="Top"
xmlns:intr="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
>
<intr:Interaction.Triggers>
<intr:EventTrigger EventName="Loaded">
<intr:InvokeCommandAction Command="{Binding Path=windowLoadedCommand}"/>
</intr:EventTrigger>
</intr:Interaction.Triggers>
<Grid x:Name="GridRegistratie">
.....
The viewmodel:
public class RegistratieViewModel
{
public RelayCommand windowLoadedCommand { get; private set; }
public RegistratieViewModel()
{
...
//commands
windowLoadedCommand = new RelayCommand(ExecuteWindowLoaded, CanExecute);
}
private bool CanExecute(object parameter)
{
return true;
}
private void ExecuteWindowLoaded(object parameter)
{
MessageBox.Show("window laden...........");
//Nothing happens
}
}
In my view i have this : (works for the other bindings)
public partial class RegistratieView : UserControl
{
public RegistratieView()
{
InitializeComponent();
DataContext = new RegistratieViewModel();
}
}