WPF Tooltip "opened" event binding to viewmodel is not working - c#

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>

Related

MVVM How bind MouseLeftButtonDown and MouseLeftButtonUp in Canvas

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>

MVVM LightToolkit and WPF Datagrid AutoGeneratingColumn event

Is it possible to use MVVMLight Toolkits EventToCommand approach for handling Datagrid's AutoGeneratingColumn event? I tried the following approach, but it doesn't seem to work:
<i:Interaction.Triggers>
<i:EventTrigger EventName="AutoGeneratingColumn">
<mvvm:EventToCommand Command="{Binding TestCommand}"> </mvvm:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
Yes it is.
I'd recommend setting your Xaml and Command Signature as I've outlined below.
XAML
<i:Interaction.Triggers>
<i:EventTrigger EventName="AutoGeneratingColumn">
<mvvm:EventToCommand Command="{Binding TestCommand}" PassEventArgsToCommand="True" />
</i:EventTrigger>
</i:Interaction.Triggers>
C# - In your DataContext (ViewModel)
public void Test(AutoGeneratingColumnEventArgs e)
{
// handle however you need to here
}

How to use EventToCommand - Error in XAML

The user input something in the TextBox and hits the Enter-button. When the Enter-button is hit the AddFieldCommand is called. How do I do what in XAML?
My code is giving me a warning: "The Property 'Text' is set more than once".
I need to know which object in the Canvas that is being updated, so I can add the content from the TextBox to my model - this is why I use EventToCommand.
<TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty, UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" >
<TextBox.InputBindings>
<KeyBinding Key="Enter" >
</KeyBinding>
</TextBox.InputBindings>
<i:EventTrigger EventName="AddField">
<cmd:EventToCommand Command="{Binding DataContext.AddFieldCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" PassEventArgsToCommand="True"/>
</i:EventTrigger>
</TextBox>
Can anybody help?
In XAML, everything that’s placed inside an element becomes its content. For text boxes, this sets the Text property. This is to allow things like this:
<TextBox>Foo bar</TextBox>
So you can place the content within the XAML elements. This is equivalent to this:
<TextBox Text="Foo bar" />
Now, if you look at your XAML code, you will notice that you have two elements inside the TextBox element: TextBox.InputBindings and i:EventTrigger. To explain the first, you need to know that there is another way to specify an element’s property values, by using child elements. This makes the above examples equivalent to this:
<TextBox>
<TextBox.Text>Foo bar</TextBox.Text>
</TextBox>
This works for all properties of TextBox. Now, InputBindings is an property of TextBox, so having it as a child element will correctly set the property and it will also not affect the element’s content value (so Text isn’t set by its presence). However, i:EventTrigger is not an property of TextBox, so this will set the content of the TextBox—giving the error message you see.
To use interaction event triggers, you need to place these into the attached property i:Interaction.Triggers. As an attached property, it can be set with a child element like above. So, your code should look like this:
<TextBox …>
<i:Interaction.Triggers>
<i:EventTrigger EventName="AddField">
<cmd:EventToCommand … />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
You can use ICommand interface to execute your command and use IsDefault=true property of the button which allows it to remain focus.So when you click enter it will execute the Command you binded on the button.
<TextBox x:Name="txtFields" Text="{Binding FieldsTextProperty,UpdateSourceTrigger=PropertyChanged}" Height="23" TextWrapping="NoWrap" Background="#FFCBEECD" AcceptsReturn="False" />
<Button Name="btnEnter" IsDefault="True" Command="{Binding DataContext.AddFieldCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" />

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