MVVM How bind MouseLeftButtonDown and MouseLeftButtonUp in Canvas - c#

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>

Related

I can't use ActionMessage from caliburn micro, how do I resolve it?

From what I read in the description of Caliburn Micro, this code should be compiled without problems. Caliburn Description
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="AbrirPDF">
<cal:Parameter Value="{Binding CNPJ}"/>
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
When trying this, I get the following error:
ArgumentException: Cannot add instance of type 'ActionMessage' to a collection of type 'TriggerActionCollection'. Only items of type 'T' are allowed.
Could someone help me solve this problem?
You probably have the wrong namespace mappings. This should compile:
<UserControl x:Class="CaliburnMicroSample.Views.ShellView"
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"
xmlns:cal="http://www.caliburnproject.org">
<StackPanel>
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:ActionMessage MethodName="AbrirPDF">
<cal:Parameter Value="{Binding CNPJ}"/>
</cal:ActionMessage>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
</UserControl>
The only installed NuGet package is Caliburn.Micro 3.2.0.
I had similar issues I had to add an extra xaml tag before calling ActionMessage my corresponding sample to get it to work was:
<StackPanel>
<Button>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<cal:Action.Target>
<cal:ActionMessage MethodName="AbrirPDF">
<cal:Parameter Value="{Binding CNPJ}"/>
</cal:ActionMessage>
</cal:Action.Target>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</StackPanel>
Then I was able to access the specified tag.
For Caliburn.Micro v4 I found that changing the namespaces to the following fixed my issue and I did not have to add the extra <cal:Action.Target> tags
xmlns:cal="http://caliburnmicro.com"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
Previously I had been using the following namespaces
xmlns:cal="clr-namespace:Caliburn.Micro;assembly=Caliburn.Micro.Platform"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

Triggering a command with a command target

*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}"

Button inside the GridSplitter not working WPF MVVM

I put the button inside the gridsplitter. my intention is to make clickable gridsplitter as well as slideable. my problem is after putting button inside the grid splitter, totally cannot drag by mouse. how can i configure the grid splitter to clickable and slideable.
<GridSplitter BorderThickness="1" HorizontalAlignment="Stretch" Grid.Column="1" >
<GridSplitter.Template>
<ControlTemplate TargetType="{x:Type GridSplitter}">
<Grid>
<Button Name="btnSplit" Content="⁞" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding SplitterClickCommand}" CommandParameter="{Binding ElementName=btnSplit}" ></i:InvokeCommandAction>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Grid>
</ControlTemplate>
</GridSplitter.Template>
</GridSplitter>
Best Rgds
df
Try to subscribe MouseDoubleClick event on GridSplitter:
<GridSplitter BorderThickness="1" HorizontalAlignment="Stretch" Grid.Column="1" >
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<i:InvokeCommandAction Command="{Binding SplitterClickCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</GridSplitter>
If MouseDoubleClick event is not suitable for you, you can try to subscribe to MouseDown or MouseLeftButtonDown.

wpf eventtrigger usercontrol inside stackpanel

I have a stackpanel containing usercontrols with eventtriggers. These eventtriggers is used to select a usercontrol, which works just fine.
Now i want to make it possible to deselect selected usercontrol by clicking in the stackpanel outside a usercontrol. This is here my problem occur.
I have tried to add an eventtrigger to the stackpanel, but it wont work when clicking in the stackpanel only when clicking on one of the usercontrols inside the stackpanel and furthermore then overrule the usercontrol own eventtrigger.
<StackPanel Name="DisplayArea">
<ItemsControl ItemsSource="{Binding Nodes}" />
<ItemsControl ItemsSource="{Binding Edges}" />
<StackPanel.Triggers>
<EventTrigger RoutedEvent="StackPanel.Loaded">
</EventTrigger>
</StackPanel.Triggers>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<cmd:EventToCommand Command="{Binding DataContext.MouseDownPanelCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</StackPanel>
I understand that this isn't the right way to do it, but i can't figure out how to.
Hope you guys understand my problem.

Binding toggle button to two commands

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.

Categories