WPF Interaction Trigger CallMethodAction - c#

I have Used Event Trigger in my View part given code as below. Almost all bindings are properly with ViewModel class - MainWindowViewModel, but for the method "CustomRibbonWindow_Loaded", its throwing runtime exception like :
An exception of type 'System.ArgumentException' occurred in Microsoft.Expression.Interactions.dll but was not handled in user code
Additional information: Could not find method named 'CustomRibbonWindow_Loaded' on object of type 'MainWindow' that matches the expected signature.
If there is a handler for this exception, the program may be safely continued.
I have tried putting putting TargetObject="{Binding ElementName=RR}" as well as TargetObject="{Binding}" also. But none of seems working.
My method way in VM is as below,
private void CustomRibbonWindow_Loaded()
{
...
}
Please guide how to resolve.
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<si:CallMethodAction MethodName="CustomRibbonWindow_Loaded"/>
</i:EventTrigger>
</i:Interaction.Triggers>
MainWindow.xaml
<custom:CustomRibbonWindow x:Class="gDispatchApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Fluent="clr-namespace:Fluent;assembly=Fluent"
xmlns:custom="clr-namespace:gDispatchAppLib.Helpers.CustomUIControls;assembly=gDispatchAppLib"
xmlns:DockUI="clr-namespace:DockingLibrary;assembly=DockingLibrary"
xmlns:UserControls="clr-namespace:gDispatchAppLib.View.UserControls;assembly=gDispatchAppLib"
xmlns:AppWindows="clr-namespace:gDispatchAppLib.View.AppWindows;assembly=gDispatchAppLib"
xmlns:VM="clr-namespace:gDispatchAppLib.ViewModel.AppWindows;assembly=gDispatchAppLib"
xmlns:VM2="clr-namespace:gDispatchAppLib.ViewModel;assembly=gDispatchAppLib"
xmlns:PE="clr-namespace:gDispatchAppLib.ViewModel.CADQueues;assembly=gDispatchAppLib"
xmlns:wpfHelper="clr-namespace:gDispatchAppLib.WPFHelpers;assembly=gDispatchAppLib"
xmlns:conv="clr-namespace:gDispatch.MvvmValidation.WPF;assembly=gDispatch.MvvmValidation"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:si="http://schemas.microsoft.com/expression/2010/interactions"
Title="SERIS CAD"
MinHeight="300"
WindowState="Maximized" HorizontalContentAlignment="Stretch"
FlowDirection="LeftToRight" CaptionHeight="50"
IsIconVisible="False" WindowStyle="SingleBorderWindow"
xmlns:my="clr-namespace:System;assembly=mscorlib"
x:Name="RR">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<si:CallMethodAction MethodName="CustomRibbonWindow_Loaded" TargetObject="{Binding ElementName=RR}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
...
</custom:CustomRibbonWindow>

Do your method subscription like this.
private void Window_Loaded(object sender, RoutedEventArgs e)
// add the proper parameters
{
// code here
}
Here is the documentation: Link

I had the same problem. Just make it public. Thanks for your comment on the other answer :)
public void CustomRibbonWindow_Loaded()

Related

CommandParameter of MetroEventToCommand doesn't work with control(Windows universal 10)

i want to bind an event using MetroEventToCommand library.
http://metroeventtocommand.codeplex.com/
It calls the method however it doesn't give the control as parameter. It's says it's null.
this is what i have.
<ScrollViewer x:Name="test">
<ListView/>
<metroEventToCommand:EventToCommandManager.Collection>
<metroEventToCommand:EventToCommand Command="{Binding RefreshCommand}" Event="ViewChanging" CommandParameter="{Binding ElementName=test, Mode=TwoWay}"/>
</metroEventToCommand:EventToCommandManager.Collection>
</ScrollViewer>
public RelayCommand<ScrollViewer> RefreshCommand { get; set; }
private void init()
{
RefreshCommand = new RelayCommand<ScrollViewer>(Refresh);
}
private void Refresh(ScrollViewer o)
{
if (o != null)
{
}
}
thanks in advance.
OK... not quite an answer, but I can't put code in a comment. I put together a quick app using MVVM Light and using the Interactivity library instead of metroToEventCommand.
I can pass it from hooking up an event handler (of course)
private void onViewChanging(object sender, ScrollViewerViewChangingEventArgs e)
{
vm.RefreshCommand.Execute(this.test);
}
I can also get it to fire the command WITH the parameter using the Loaded event or PointerEntered event
<ScrollViewer x:Name="test" >
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="PointerEntered">
<Core:InvokeCommandAction Command="{Binding RefreshCommand, Mode=OneWay}" CommandParameter="{Binding ElementName=test}" />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
<ListView x:Name="myList"/>
</ScrollViewer>
However, the Interactivity dll throws an exception (Cannot add instance of type 'Microsoft.Xaml.Interactions.Core.EventTriggerBehavior' to a collection of type 'Microsoft.Xaml.Interactivity.BehaviorCollection'.) when trying to use the ViewChanging, ViewChanged, DirectManipulationCompleted, etc. events - whether a parameter is used or not. ManipulationCompleted does not fire the command (I've seen hints that commands cannot be bound to routed events).
So, it would seem that the concept works - but only for certain event types. I'm sorry that isn't a solution to your challenge, but hopefully it is some additional information to help your attempts.

Type reference cannot find type named Commands

I want to have custom Commands to respond to in my application.
So I was following the instructions on this answer, and created a static class for my commands:
namespace MyNamespace {
public static class Commands {
public static readonly RoutedUICommand Create = new RoutedUICommand(
"Create Thing", nameof(Create),
typeof(MyControl)
);
}
}
I then tried using it on my UserControl:
<UserControl x:Class="MyNamespace.MyControl"
...boilerplate...
xmlns:local="clr-namespace:MyNamespace">
<UserControl.CommandBindings>
<CommandBinding Command="local:Commands.Create"
CanExecute="CanCreateThing"
Executed="CreateThing"/>
</UserControl.CommandBindings>
...the control's contents...
</UserControl>
The method CanCreateThing always sets CanExecute to true. CreateThing currently does nothing.
I get this error on the usage of MyControl in the window XAML:
Type reference cannot find type named '{clr-namespace:MyNamespace;assembly=MyAssembly}Commands'.
And this one in the Command="..." attribute in the binding.
Invalid value for property 'Command': 'Microsoft.VisualStudio.DesignTools.Xaml.LanguageService.Semantics.XmlValue'
UPDATE
Mathew got rid of the errors, however, the menu items with those commands are still grayed out. Relevant code:
<TreeView ...>
<ContextMenu>
<MenuItem Command="{x:Static local:Commands.Create}"/>
</ContextMenu>
...
</TreeView>
MyControl.xaml.cs
//...
private void CanCreateThing(object sender, CanExecuteRoutedEventArgs e) {
e.CanExecute = true;
}
//...
With Mathew's help, a fix was found:
First, I had to replace all instances of local:Commands.Create with {x:Static local:Commands.Create}. However, the menu items would still be gray.
So in each menu item, I added a CommandTarget referencing the ancestor ContextMenu:
<MenuItem Command="{x:Static local:Commands.CreateTrigger}"
CommandTarget="{Binding PlacementTarget, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContextMenu}}}"/>
And that made the menu items clickable.

Using interaction trigger to call visibility changed method WPF

What I would like to figure out is two things, how to get a trigger occurring when a user control's visibility is changed and passing the value of visibility through as a parameter.
For whatever reason the trigger doesn't seem to be firing. I have only just added in the ControlVisible parameter to show what I would like to happen, when testing it was not there and just had a messagebox inside to catch when visibility changed, as in the commented out method.
I am using 4.0 with Visual Studio 2010
Main Window View which contains the user control
<Window x:Class="bt.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:vm="clr-namespace:bt"
xmlns:ctrls="clr-namespace:bt.Controls"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
mc:Ignorable="d">
<Grid>
<ctrls:Login Visibility="{Binding DataContext.Vis,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window},Converter={StaticResource BooleanToVisibilityConverter}}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="IsVisibleChanged">
<ei:CallMethodAction MethodName="VisibleTrigger" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ctrls:Login>
</Grid>
</Window>
UserControl View Model:
namespace bt.Controls
{
class LoginViewModel
{
public LoginViewModel()
{
}
public void VisibleTrigger(bool ControlVisible)
{
if (ControlVisible)
{
MessageBox.Show("Start timer");
}
else
{
MessageBox.Show("Stop timer");
}
}
//public void VisibleTrigger()
//{
// MessageBox.Show("Changed");
//}
}
}
First, we need to set TargetObject property to viewmodel/DataContext, because method to be invoked is available in the viewmodel :
......
<i:Interaction.Triggers>
<i:EventTrigger EventName="IsVisibleChanged">
<ei:CallMethodAction MethodName="VisibleTrigger" TargetObject="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
......
Second, EventTrigger doesn't seems to work specifically with IsVisibleChanged event. So code snippet above works for other event, but not IsVisibleChanged. We can find a workaround in the answer to this SO question, by using PropertyChangedTrigger to listen to Visibility property changed, instead of listening to IsVisibleChanged event :
<i:Interaction.Triggers>
<ei:PropertyChangedTrigger Binding="{Binding Visibility, ElementName=MyControlName}">
<ei:CallMethodAction MethodName="VisibleTrigger" TargetObject="{Binding}"/>
</ei:PropertyChangedTrigger>
</i:Interaction.Triggers>
Third, CallMethodAction doesn't seems to provide a way to pass parameter to the method. To be able to invoke a method with parameter we better use InvokeCommandAction instead of CallMethodAction as suggested here and also suggested by #Rohit in your previous question.

MvvmLight EventToCommand not working anymore

I have encountered a rather strange problem using the GalaSoft - MVVM Light Toolkit in a Windows Phone 8 project.
Suddenly (after merging some stuff) all my EventToCommand calls are not working anymore. They worked before. I already tried to remove the MvvmLight toolkit and reference it again with Nuget, but the result stays the same.
One example:
MainMenuPage.xaml
<phone:PhoneApplicationPage
...
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:commands="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"
....>
<phone:PhoneApplicationPage.DataContext >
<Binding Source="{StaticResource MainMenuViewModel}"/>
</phone:PhoneApplicationPage.DataContext>
<!-- catch back key press -->
<i:Interaction.Triggers>
<i:EventTrigger EventName="BackKeyPress">
<commands:EventToCommand
Command="{Binding BackKeyPressCommand}"
PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
MainMenuViewModel.cs
// back key press command
public RelayCommand<object> BackKeyPressCommand { get; set; }
public MainMenuViewModel()
{
BackKeyPressCommand = new RelayCommand<object>(
BackKeyPress,
(o) => true
);
...
}
private void BackKeyPress(Object o)
{
// handle back key press
}
This worked perfectly before, but now the BackKeyPress(Object o) Method never gets called anymore.
This happens for all EventToComamnd calls.
If I remove the xmlns tags, Resharper suggests to add this:
xmlns:command="http://www.galasoft.ch/mvvmlight"
Result of that:
The name "EventToCommand" does not exist in the namespace "http://www.galasoft.ch/mvvmlight"
Anyone encountered a similar problem or has an idea what could have caused this?
These namespaces are correct.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:commands="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WP8"
But your PhoneApplicationPage has wrong DataContext.
DataContext="{Binding Path=MainMenuViewModel, Source={StaticResource Locator}}"
MainMenuViewModel is property in the ViewModelLocator:
public MainMenuViewModel MainMenuViewModel
{
get
{
return ServiceLocator.Current.GetInstance<MainMenuViewModel>();
}
}
Btw the argument of BackKeyPress is CancelEventArgs. You should use:
public RelayCommand<CancelEventArgs> BackKeyPressCommand { get; private set; }
this.BackKeyPressCommand = new RelayCommand<CancelEventArgs>(this.BackKeyPress)
private void BackKeyPress(CancelEventArgs e)
{
}
Windows Phone 8.1
Windows 8.1 Behavior SDK: How to use InvokeAction with InputConverter to pass arguments to a Command
Microsoft has developed it's own EventToCommand functionality. It's located in Behaviors SDK. Someone on stackoverflow told to get this SDK via Nuget. If you can't find the package in NuGet - get it in Add reference dialog.
(My add reference dialog may differs from original because of Productivity Power Tools extension)
Here is example of simple usage:
<ListBox ItemsSource="{Binding Persons, Mode=OneWay}"
SelectedItem="{Binding SelectedPerson, Mode=TwoWay}">
<interactivity:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="SelectionChanged">
<core:InvokeCommandAction Command="{Binding DisplayPersonCommand}" />
</core:EventTriggerBehavior>
</interactivity:Interaction.Behaviors>
</ListBox>

How to Bind to window's close button the X-button

How I can bind one of my buttons on control to X Button that closes the window ?
I just want to create cancel button that just closes the window.
I am using MVVM in my code.
If possible to do it only in xaml, I just dont have any special code with the button click.
You can just call the Close() method, which will close the window.
private void MyButton_Click(object s, RoutedEventArgs e)
{
Close();
}
If it's WPF (and provided I remember right) you can just use CallMethodAction from the parent as a behavior and utilize Close() method via just XAML. Something like;
Parent Window x:Name="window"
namespaces;
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
-
<Button Content="Cancel">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<ei:CallMethodAction
TargetObject="{Binding ElementName=window}"
MethodName="Close"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
Hope this helps.
MVVM solution without code-behind could also look like this:
View:
<Button Content="Cancel" Command="{Binding CloseWindowCommand}" CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />
ViewModel:
public ICommand CloseWindowCommand
{
get
{
return new RelayCommand<Window>(SystemCommands.CloseWindow);
}
}
But SystemCommands is from .net-4.5 so if you rock in some older version of .net you can also use following.
public ICommand CloseWindowCommand
{
get
{
return new RelayCommand<Window>((window) => window.Close());
}
}

Categories