MVVM Light, Mahapps metro and EventToCommand via EventTrigger from System.Windows.Interactivity - wpf

I'm going nuts on this one:
I have an application using both Mahapps.Metro as well as MVVMLight.
Basically most things are ok UNTIL you try to use Interaction.Triggers.
I typically end up with errors like
Cannot add instance of type 'EventToCommand' to a collection of type 'TriggerActionCollection'. Only items of type 'T' are allowed.
A way to reproduce this is via a repo I found online:
https://github.com/mike-schulze/mahapps-mvvmlight-setup
(sorry mike for hijacking) and adding a metro SplitButton to the viewmodel:
<Controls:SplitButton ItemsSource="{Binding MyList}" Grid.Column="1" Grid.Row="1">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand
Command="{Binding Mode=TwoWay, Path=SelectionChangedCommand}"
PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Controls:SplitButton>
And MyList being
public List<string> MyList
{
get
{
List<string> theList = new List<string>();
theList.Add("Hello");
theList.Add("World");
return theList;
}
}
I'm not sure how many different namespaces, hard coded Interactivity versions in App.config or what so ever I tried.
Has anyone a working example with Mahapps Metro (version not too old) and MVVM Light and the EventToCommand stuff?
I thought my problem is related to updates to Metro - and them using Behaviors now instead of Interactivity. I'm using the Interactivity dll version 4.5.0.0.
But even the old git I mentioned above shows the problem... And I can't find a working solution.
Any help is greatly appreciated.
Thanks

You need to add the namespace for System.Windows.Interactivity too.
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Because MVVMLight uses this version of Interactivity.
<mah:MetroWindow x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
...
xmlns:mah="http://metro.mahapps.com/winfx/xaml/controls"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
...
DataContext="{Binding Main, Source={StaticResource Locator}}">
...
<mah:SplitButton ItemsSource="{Binding MyList}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<command:EventToCommand Command="{Binding Mode=TwoWay, Path=SelectionChangedCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
</mah:SplitButton>
...
</mah:MetroWindow>

Related

Disable Triggers in Design Time

Im developing a WPF Application with a TabControl. Inside the TabItems of this TabControl I have implemented EventTriggers which react on a LeftButtonMouseDownEvent to do some stuff. My Problem is that during Design Time of Visual Studio the Event is triggered and it seems to block any further interactions in the Design Window.
Is there a possibility to ignore the trigger, when my Visual Studio is in Design Time. I would prefer to do this in pure XAML. I know that there exists the "mc:Ignorable" tag, but I want it the other way round. If needed i posted a Code Snippet for you.
Thanks for your help!
<TabItem>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<SomeAction/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TabItem>
I don't know how to do it in xaml, but, may be, adding to code SomeAction this, will resolve your problem.
var isInDesignMode = DesignerProperties.GetIsInDesignMode(new DependencyObject());
if(isInDesignMode)
{
// using in VisualStudio or Blend
}
else
{
// using in application
}
Try extending mc:Ignorable with i for your case, i.e. mc:Ignorable="d i":
<UserControl ...
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
...
d:DesignHeight="600"
d:DesignWidth="800"
...
mc:Ignorable="d i">
...
<TabItem>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<SomeAction/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TabItem>
...
</UserControl>

MouseDoubleClick-CommandBinding for WPF-ToolKit's DoubleUpDown not working?

I'm using the DoubleUpDown UserControl from the Extended WPF Toolkit in my current project. Now I have to bind a RelayCommand to the DoubleClick event of that DoubleUpDown, but it is not working. I've assigned that DoubleClick to all kinds of different UserControls so far and usually it was working fine or sometimes I had to wrap it into an empty UserControl-Element which would then hold the CommandBinding, but so far I always got it working.
This is what I tried so far:
<UserControl Grid.Row="7"
Grid.Column="0">
<xctk:DoubleUpDown Value="{Binding EditableDevice.SelectedLoadReceptor.DecimalPlaces,
UpdateSourceTrigger=PropertyChanged,
Mode=TwoWay, FallbackValue='1'}"
FormatString="F0"
Minimum="0"
Maximum="10">
<xctk:DoubleUpDown.InputBindings>
<MouseBinding Command="{Binding EditDeviceCommand}"
Gesture="LeftDoubleClick" />
</xctk:DoubleUpDown.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="LeftDoubleClick">
<cmd:EventToCommand Command="{Binding EditDeviceCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</xctk:DoubleUpDown>
<UserControl.InputBindings>
<MouseBinding Command="{Binding EditDeviceCommand}"
Gesture="LeftDoubleClick" />
</UserControl.InputBindings>
</UserControl>
I'm usually fine with using the InputBindings, but not with the DoubleUpDown...
I wonder what is causing the issue. Does anyone here have an idea or a workaround?
Regards
Ralf
Hmm, still couldn't figure out what is wrong here. In the meantime I'll just use CodeBehind where ever possible by using the regular MouseDoubleClick-Event.

WPF Bingmaps pushpin event binding mvvm

I would like to trigger a command in my ViewModel when the pushpin is clicked on the map. How can I achieve this using databinding?
Here is the DataTemplate I am using for the pinpoints:
<DataTemplate x:Key="PushPinTemplate">
<map:Pushpin Cursor="Hand"
map:MapLayer.Position="{Binding Location}">
</map:Pushpin>
</DataTemplate>
A colleague found the solution:
After adding the Nuget Package System.Windows.Interactivity.WPF
and adding the xml namespace
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
you can add an EventTrigger to the template, here the full template code, where
CachePushPinClicked is an ICommand
<DataTemplate x:Key="PushPinTemplate">
<map:Pushpin Cursor="Hand"
map:MapLayer.Position="{Binding Location}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:InvokeCommandAction Command="{Binding CachePushPinClicked}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</map:Pushpin>
</DataTemplate>

WPF mvvm wizard

I am implementing WPF MVVM Wizard and I am wondering about the right approach of performing a DoOperation when a new Wizard’s Page (UserControl) is loaded.
The DoOperation is implemented on the MyWizard.ViewModal class while the UserControl Load is happening at the MyWizard.View namespaces.
How can I connect between the UserControl loaded event to the DoOperation api?
I tried the following:
<xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding Path=RunOperation}"/
</i:EventTrigger>
</i:Interaction.Triggers>
RunOperation calls DoOperation.
it doesn’t work, RunOperation is not being called.
This is the right approach or there is a better way to perform an operation at the MyWizard.ViewModal class?
Your approach should work. Have you checked your output console for binding errors? Is RunOperation a command? Is the DataContext of the UserControl already set, when the Loaded event is raised? Have you implemented the triggers like this in your UC?
<UserControl x:Class="..."
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding Path=RunOperation}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Grid>
...
</Grid>
</UserControl>

Routed Events of TextBlock

How to fire RoutedEvents of TextBlock in ViewModel from code behind in wpf.
Kindly let me know, how I can bind routed events in wpf code behind. Thanks
Well I use this (you will need System.Windows.Interactivity in Silverlight, but I suspect it's similar in WPF):
xmlns:GalaSoft_MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<TextBlock Text="{Binding InputValue, Mode=TwoWay}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="GotFocus">
<GalaSoft_MvvmLight_Command:EventToCommand Command="{Binding InputValueGotFocusCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBlock>
You can do this easy in Blend

Resources