I have a toggle button in my silverlight application as follows:
<ToggleButton Content="ToggleButton" Margin="0,30,0,0" Style="{StaticResource ChkToggleButton}" />
The toggle currently is changing visual states on toggle and nothing more.
However, I need to bind each of the toggle with a different command. For eg: On button press1, run command1 and on button press again, run command2.
How can this be done?
Use Triggers for such purposes:
<ToggleButton Content="ToggleButton" Margin="0,30,0,0" Style="{StaticResource ChkToggleButton}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Checked">
<i:InvokeCommandAction Command="{Binding FirstCommand}"
CommandParameter="{Binding SomeParameter}" />
</i:EventTrigger>
<i:EventTrigger EventName="Unchecked">
<i:InvokeCommandAction Command="{Binding SecondCommand}"
CommandParameter="{Binding AnotherParameter}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</ToggleButton>
If you don't have Interactivity you can get it by installing Expression Blend SDK or as a NuGet package.
use a single command and also keep track of the toggle state.
Have a viewmodel (preferably, or some codebehind) and let it use these two inputs to decide what actually needs to be done.
Related
I spend a lot of time to understand why it is not working, it just MUST work but it doesn't...
Let's imagine I have ItemsControl binded to ObservableCollection. Inside ItemsControl.ItemTemplate there are StackPanel with buttons, textblocks etc.
I want to bind ToolTip Opened event attached to StackPanel to my Command, and I need instance of model also.
<StackPanel.ToolTip>
<ToolTip>
<TextBlock Text="Example text"></TextBlock>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Opened">
<i:InvokeCommandAction Command="{Binding Path=DataContext.TooltipOpenCommand, ElementName=MapsControl}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ToolTip>
</StackPanel.ToolTip>
My C# code is:
public ICommand TooltipOpenCommand => new RelayCommand(ToolTipOpen);
public void ToolTipOpen(object obj)
{
MessageBox.Show("Test message");
}
(RelayCommand is just default Command example from internet with execute and CanExecute)
So, when I hover mouse on StackPanel, tooltip with "Example text" is appears but command is not executed, I can't ever understand why, what am I doing wrong?
By the way, to prove that it MUST work, check this code(it attached just to the same StackPanel in example above, but not to tooltip). AND THIS CODE IS WORKING!!! But the code above isn't...
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseEnter">
<i:InvokeCommandAction Command="{Binding Path=DataContext.TooltipOpenCommand, ElementName=MapsControl}"
CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
Im trying to add new child(circle) to my Canvas after user click on it. And i want to change position of circles while draging them.
I want to do it with MVVM but dont know how catch these events in ViewModel.
I need a MouseLeftButtonUp/Down
I've tried wih System.Windows.Interactivity but it didnt helped.
My only idea is to add invisible button and do easy binding Command="{Binding Method}", but it still wont solve my problem, and certainly its not a best option
This in my XAML code (part of it)
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
<Canvas x:Name="DrawableCanvas" HorizontalAlignment="Left" Height="{Binding ElementName=GridContainer, Path=ActualHeight}" VerticalAlignment="Top" Width="{Binding ElementName=GridContainer, Path=ActualWidth}" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:InvokeCommandAction Command="{Binding CanvasActionCommand}" x:Name="interactifityFix2">
</i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Canvas>
Add this namespace in your XAML:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
then you can add an interaction trigger wich will merge the event with an icommand in your viemodel like so:
<Ellipse>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewMouseDown">
<i:InvokeCommandAction Command="{Binding MouseDownCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Ellipse>
*I'm using Material Design though this shouldn't be relative to the question
<ScrollViewer>
<ListView>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{x:Static materialDesign:DialogHost.OpenDialogCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ListView>
</ScrollViewer>
Sofar I've gotten it to trigger the command on double click, although I want to also set a command target property like:
CommandTarget="{Binding ElementName=addhost}"
I've encountered a problem with events using WpfAnimatedGif NuGet package. Package has two additional events for <image> but I'm unable to use them with MVVM pattern. I've tried interactivity:
<Window
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:gif="http://wpfanimatedgif.codeplex.com">
<Image gif:ImageBehavior.AnimatedSource="animation.gif">
<i:Interaction.Triggers>
<i:EventTrigger EventName="AnimationCompleted">
<i:InvokeCommandAction Command="{Binding SomeCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</Window>
but it fails, command doesn't get called. I've messed around a bit and got it kinda working (not realy). If I leave EventTrigger's EventName unspecified command does get called but on AnimationLoaded event only:
<i:EventTrigger>
<i:InvokeCommandAction Command="{Binding SomeCommand}"/>
</i:EventTrigger>
In this situation command is called properly. However, I'm interested in AnimationCompleted event.
P.S. Everything works fine without MVVM.
I'm having a go at writing a small media player for my Windows Phone (more for learning purposes if anything), and am using mvvm-light.
When a video is playing, I have a timer that periodically updates the slider position (and ensures that it's in sync). When I slide the slider around, I pause the timer, so it doesn't skip about.
I use the ManipulationStarted event to pause the timer, and ManipulationComplete to resume it.
I've tried using EventToCommand, but only the ManipulationStarted event fires. When I lift my finger off the phone, ManipulationComplete doesn't fire.
This is my xaml :
<Slider x:Name="PlaybackSlider" HorizontalAlignment="Stretch" Margin="20,0" VerticalAlignment="Bottom" Maximum="{Binding MaxSteps}" Value="{Binding Offset, Mode=TwoWay}" Style="{StaticResource SliderStyle1}" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="ManipulationStarted">
<Command:EventToCommand Command="{Binding PlayOffsetBegin}"/>
</i:EventTrigger>
<i:EventTrigger EventName="ManipulationCompleted">
<Command:EventToCommand Command="{Binding PlayOffsetEnd}"/>
</i:EventTrigger>
<i:EventTrigger EventName="MouseMove">
<Command:EventToCommand Command="{Binding PlayOffsetUpdate}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Slider>
The bindings are relay commands.
If I implement it like this, it all works fine :
<Slider x:Name="PlaybackSlider"
ManipulationStarted="PlaybackSlider_ManipulationStarted"
ManipulationCompleted="PlaybackSlider_ManipulationCompleted"
HorizontalAlignment="Stretch" Margin="20,0" VerticalAlignment="Bottom"
Maximum="{Binding MaxSteps}" Value="{Binding Offset, Mode=TwoWay}"/>