We have implemented a simple InputBinding for mouse click gestures, the code is something like below:
<Image.InputBindings>
<MouseBinding MouseAction="LeftClick" Command="{Binding OpenDialogCommand}" />
<MouseBinding MouseAction="LeftDoubleClick" Command="{Binding OpenDialogCommand}" />
</Image.InputBindings>
We expected that WPF is able to recognize Left and LeftDouble gestures and do the respective command. But in practice we found that the Left Click is evaluated first and the second click of the double click is treated as another single click. Since our command is to open a dialog doing a doubleclick will quickly open and close our dialog.
Does anyone meet such thing before?
Thanks.
S.
I think this is the desired behavior. Note that it is a LeftClick event, which doesn't necessarily mean "LeftSingleClick". You should check out the Snoop utility for investigating exactly which events are getting triggered.
Related
I have a UI with a few controls.
Initially when form loads, search button will be disabled, once all
search criteria are given, search button will be enabled
automatically.
On click on search button, I want to call the method
using MVVM pattern and bind the result in grid
XAML:
<Button Name="btnGetDetails" Content="Get Details" Grid.Row="2" Command="{Binding SearchCommand}"/>
What code is required in model, view model and XAML?
Command will be executed only when the button will be clicked on. If you need to do something to the button then you should do it to the Window that contains the button (assuming your button is in a Window). Now if you want to stick with the MVVM pattern then you should not use the Window.OnLoaded, because that would put code in your code behind. One option is to use System.Windows.Interactivity, which you have download seperately. Here is what it will look like:
<Window x:Class="..."
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">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding ...}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Window>
As for what your Model, View and ViewModel should be, I think you should check out some tutorials on the web. There are some very good explanations on how to implement the MVVM pattern. I found this youtube video pretty informative myself:
http://www.youtube.com/watch?v=EpGvqVtSYjs
So some MVVM basics here. You're on the right track, just missing a step. Your Command implementation in your view model should (potentially) accept two inputs: An Action representing the executing code, and a Predicate that returns true/false on whether you can execute the code in the Action block. So, in your view model, define your command along the lines of (note: this is a sample from one of my projects):
this.executeCommand = new RelayCommand(this.OnExecuteClicked, this.OnCanExecuteChanged);
The OnCanExecuteChanged method will return a bool based on whatever criteria you set up. So, if you want the submit button enabled when property A and property B have been properly set up, then return true, else return false. The internal workings of your command implementation will take care of the rest. Do a search for a RelayCommand implementation (if you don't have it already) or a DelegateCommand for further samples.
I'm attempting to use a Command, defined in my view model with EventTriggers as defined in xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
I have changed the control from a Microsoft.Surface.Presentation.Controls.SurfaceSlider-derived control to a regular WPF Button. With the Button, the same ConfirmOrderCommand gets fired if I use the EventName="MouseEnter", but if I use EventName="Click" nothing happens. The XAML for the Button is here.
<Button Name="ConfirmButton"
IsEnabled="{Binding IsEnabled}"
Style="{StaticResource ConfirmButtonStyle}"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding ConfirmOrderCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
I want the user to be able to click the button to fire the command. Can I get the Click event to work for a Button, or do I need to look for another event? I've also failed to get MouseLeftButtonUp to work.
Try EventName="Button.Click". Anyways, you can just set the Command Property of the Button itself, and remove the Interaction.Triggers part.
The actual reason the Button.Click would not work, was determined after much pain and finally asking someone on the project after he woke up in the morning.
Our application was stealing almost all of the Button events with FrameworkElement Preview delegates.
public static void RegisterEvents(FrameworkElement parent)
{
parent.PreviewMouseDown += MouseDown;
parent.PreviewMouseUp += MouseUp;
// even more of these
}
The delegates would then use System.Window.Input.TouchDevice to ReportDown() in the case of MouseDown etc. All this time I just thought I didn't know how the standard WPF button usually works. I guess the moral of this story is events don't have to start at the child control and then propagate up to their containers until Handled = true. Preview allows the container to capture the events first.
In my window, I have this:
<UIElement.InputBindings>
<KeyBinding Gesture="Ctrl+Left" Command="{Binding MoveTaskCommand}" CommandParameter="{x:Static plugin:MoveDirection.Left}"/>
...
And down in the tree, I have this:
<Button HorizontalAlignment="Left"
ToolTip="Promote to Parent Level (Ctrl+Left)" Command="{Binding MoveTaskCommand}"
CommandParameter="{x:Static plugin:MoveDirection.Left}">
...
I don't like the redundancy, and I don't like copy pasting my hotkey's "Ctrl+Left" into the tooltip. I'm 99% certain WPF has a better way of doing it than this.
Could someone point me in the right direction?
Could someone point me in the right direction?
Option 1: I would try using a custom Attached Property maybe "IsToolTipGesture". In the PropertyChangedCallback, check if there's a ToolTip and any UIElement.InputBindings. If there are, update the ToolTip with the appropriate information from the InputBindings.
Option 2: Another thing to try if you want this behavior on ALL elements below a certain root is using a similar approach with an attached property and recursively checking child elements (via VisualTreeHelper) to see if they have a ToolTip and any InputBindings.
I have an application with limited screen space, so I'm trying to conserve some real estate by putting a combo box within a button. Its pretty nifty and it looks exactly like what I wanted it to look like. The problem is, every time I click the down arrow on the combo box, the Button also receives a click event. The drop down menu still works properly, but my button has already fired before I've had a chance to actually select what I wanted.
Here is my WPF code that describes my Button and its contents.
<Button FontSize="14" Height="32" HorizontalAlignment="Left" Click="DisableCopierButton_Click">
<StackPanel Orientation="Horizontal">
<Label Content="Disable Copier:" />
<ComboBox Name="DisableCopierComboBox">
<ComboBoxItem Content="1"/>
<ComboBoxItem Content="2"/>
</ComboBox>
</StackPanel>
</Button>
My question is, when I'm clicking on the ComboBox and only the ComboBox, how do I prevent the click event from passing through the button that is underneath it?
I finally found it. I went with the solution provided by Rachel here, even though it was not selected as the answer.
private void EnableCopierButton_Click(object sender, RoutedEventArgs e)
{
if (!(e.OriginalSource is Button))
{
// combo box was clicked, not the button, so get out of here.
return;
}
}
This seems like a SplitButton, yeah. Don't reinvent the wheel. Plenty of implementations on the web.
I recommend WPF Toolkit Extended's.
Rather than making the combo box be part of the button's Content, you may want to try creating a ContentTemplate for the button that includes a combo box.
I'am just coding some global gesture handlers for a wpf application. For example I am supposed to use right click as a trigger to proceed UI.
<Window.InputBindings>
<MouseBinding MouseAction="RightClick" Command="NavigationCommands.NextPage"/>
</Window.InputBindings>
But now the problem appears that <ListBox/> consumes all mouse button events. I did some research but didn't found an easy way to make it just be unaware of the right button. Did anybody ever had this problem and found a solution? Thanks in advance.
You should be able to prevent the ListBox from consuming the mouse clicks using the following:
<ListBox>
<ListBox.InputBindings>
<MouseBinding MouseAction="RightClick" Command="ApplicationCommands.NotACommand" />
</ListBox.InputBindings>
</ListBox>