I am learning about MVVM and Commands in WPF. I have a couple of buttons and I want to trigger similar commands depending on the fact if the buttons are clicked with the left or right mouse button.
Until now I used Event Handlers and I was able to determine which mouse button was pressed by checking the MouseButtonEventArgs.
<Button Content="Command Test" PreviewMouseDown="Button_PreviewMouseDown"/>
Current code behind:
private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
if (e.LeftButton == MouseButtonState.Pressed) {
Debug.Print("Left");
}
else {
Debug.Print("Right");
}
}
But I don’t see anything similar if I use Commands.
How can I set different commands for a button? One command when the left mouse button is clicked and another command when the right mouse button is clicked?
<Button Content="Command Test" Command="{Binding PressLetterCommand, Mode=OneWay}"/>
Currently the Command only fires when the left mouse button is clicked. If the command would also be fired if the right mouse button is clicked and I can find out which button was clicked that would be also a solution.
I searched and I found this question and answer which uses Decorator. How do I bind a command to e.g. the right mouse button in a ControlTemplate in WPF? I tried it but as far as I understand this won’t work for my buttons.
Any suggestions?
Try this
<Button Content="Command Test">
<Button.InputBindings>
<MouseBinding Gesture="RightClick" Command="{Binding PressLetterCommand}" />
</Button.InputBindings>
</Button>
Related
I'll give some details below, but briefly I have a problem wherein a button in my WPF application will disable itself if I click somewhere else in the application. This button is linked to a Command but there is absolutely NOTHING bound to the IsEnabled property of the button and the Command CanExecute callback just sets e.CanExecute to true.
I saw this similar SO question (Weird problem where Button does not get re-enabled unless the mouse is clicked) but it was not helpful.
The application is simple and consists of a DockPanel divided into 4 parts. The left section contains a DataGrid and the right section contains a UserControl that also contains a couple DataGrids as well as the offending Button. It's so weird, but if I click on any row in the left DataGrid, the Button in the right section becomes disabled. The only way I can then re-enable it is to click on any row in either of the DataGrids in the right section!
Again, there IS absolutely nothing bound to the IsEnabled property of the button or any other code/markup implicitly in place that would allow this to happen.
Some relevant code snippets:
UserControl Command bindings:
<UserControl.CommandBindings>
<CommandBinding Command="cmd:DBScriptCommands.LoadScripts" CanExecute="cmdLoadScripts_CanExecute" Executed="cmdLoadScripts_Executed" />
<CommandBinding Command="cmd:DBScriptCommands.RunScripts" CanExecute="cmdRunScripts_CanExecute" Executed="cmdRunScripts_Executed" />
</UserControl.CommandBindings>
Button xaml:
<Button IsEnabled="True" x:Name="btnLoadScripts" Command="cmd:DBScriptCommands.LoadScripts">
<StackPanel HorizontalAlignment="Stretch">
<Image Source="/Images/folder-open.png" />
<TextBlock>Load Scripts</TextBlock>
</StackPanel>
</Button>
CanExecute for Command:
private void cmdLoadScripts_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
This has me baffled and any ideas are appreciated. If more information is needed, please let me know.
Edit 1:
Seems like it is something to do with the Command (still not sure what) - if I remove the Command parameter from the Button, the problem goes away - not useful because I want the button to trigger the Command, but interesting. In the CanExecute(), if I set e.CanExecute to false, the button is always disabled which makes sense. When it is set to true (like it is now) then I have the problem I've describe where it seems like something is setting it to false by magic sometimes.
Thanks
I have a grid with a load of textblocks inside and a flyout with various options attached to the grid.
<FlyoutBase.AttachedFlyout>
<MenuFlyout>
<MenuFlyoutItem x:Name="EditButton" Text="Edit" Click="EditButton_Click"/>
<MenuFlyoutItem x:Name="DeleteButton" Text="Delete"/>
</MenuFlyout>
</FlyoutBase.AttachedFlyout>
The problem is that the flyout will appear in the same fixed spot somewhere in the middle of the grid or I can set it programmatically to appear at an element. I want it to appear wherever the mouse was right clicked. Is this possible or am I going about this the wrong way?
I don't know how are you showing the Flyout, but in my app, I use the RightTapped event of my ListView and following code in the RightTapped event handler to achieve the same thing as you want.
private void MyListView_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
var tappedItem = (UIElement)e.OriginalSource;
var attachedFlyout = (MenuFlyout)FlyoutBase.GetAttachedFlyout(MyListView);
attachedFlyout.ShowAt(tappedItem, e.GetPosition(tappedItem));
}
In my application I have a Previous Button and a Next Button. When they are clicked, a particular function is called with different parameters.
I was wondering if there was a way that the Mouse ScrollWheel and the Left and Right keyboard keys could be bound to have the same result as clicking on these two Buttons?
I.E Pushing upwards on the ScrollWheel or Pressing the Right Key on the keyboard would be tantamount to clicking the Next Button and vice versa.
You can use Attached Behaviors. Create a behavior with command and parameter properties and bind. In the property changed just hook on needed events. Like here for MouseUp.
For the left and right key you could do it like this:
<Grid.InputBindings>
<KeyBinding Key="Left" Command="{Binding ExecutePreviousCommand}" />
<KeyBinding Key="Right" Command="{Binding ExecuteNextCommand}" />
</Grid.InputBindings>
I have a WPF application and I added a ContextMenu for a grid. The user makes a selection on the grid and thereafter; a ContextMenu appears. I have some textboxes on the ContextMenu where the user can enter some values but if the user clicks the ContextMenu itself (and not inside the textbox) the dialog disappears. I want to prevent this and I tried to get some event that dictate when the ContextMenu has been clicked.
private void CreateContextMenu()
{
detectionInfoContextMenu = new ContextMenu(); //create an instance of the class
//selectionBoxCanvas.ContextMenu = detectionInfoContextMenu;
playVideoGrid.ContextMenu = detectionInfoContextMenu;
detectionInfoContextMenu.MouseDown += detectionInfoContextMenu_MouseDown;
}
void detectionInfoContextMenu_MouseDown(object sender, MouseButtonEventArgs e)
{
if(e.LeftButton == MouseButtonState.Pressed)
MessageBox.Show("You clicked me!");
}
I am trying to get the Mouse button events to determine if the Left mouse button was clicked. This seems to work very well on other control e.g. canvas etc but does not seem to work here on the ContextMenu. Am I using the wrong event?
You can use StaysOpenOnClick to prevent the closing of the menu:
<MenuItem StaysOpenOnClick="True">Test</MenuItem>
Or you use a Popup as Ivan Zub suggested in the comments.
And here an example with a TextBox inside the menu:
<ContextMenu>
<MenuItem StaysOpenOnClick="True">
<MenuItem.Header>
<TextBox Width="100" />
</MenuItem.Header>
</MenuItem>
</ContextMenu>
I have created a button using XAML and have defined some simple properties for it.
<Button Name="btnNext" Grid.Row="1" Content="PARA" Width="200" Grid.Column="1" Background="#FF2D2D2D" HorizontalAlignment="Right" FontSize="40" Height="380" BorderThickness="0" />
It happens that when I click on the button or put the mouse over, it changes color.
I have tried to escape this behaviour in the btnNext_Click method but it does not affect anything.
private void btnNext_Click(object sender, RoutedEventArgs e)
{
Button button = sender as Button;
if (button != null)
{
button.Background = new SolidColorBrush(hexToColorConvertor("#FF2D2D2D"));
START_POINT += (uint)NUMBER_OF_BUTTONS1;
ReadFile(START_POINT);
}
}
Does anyone have any idea how to resolve this?
In XAML, button have default style for different states like Normal, MouseOver, Pressed etc..
Whenever button moves from one state to another, it changes its look using default style obviously. You can find more information related to default style here
Now, If you want to override this default behavior, you can do it easily with Expression-blend. More of this can be found here and here
Hope this information will help you.. :)