Remove focus from textbox when clicking on parent grid in MVVM - c#

I have a simple window that has a few buttons and a textbox. I want that when I press "Enter" on my keyboard this will trigger a button command but the problem is that when I'm focused on the textbox, I can't press "Enter" because it will just add a linebreak to the textbox.
I tried binding a LeftClick gesture of the grid to a command that uses keyboard.ClearFocus() but I guess that isn't the right function because that didn't work.
Another option which might work but I didn't try yet and I'm not sure if it's even a good practice, is adding x:Name to the textbox, and sending the window as the parameter to the command.
I want that when I click the parent grid of the textbox the focused will be removed from it so I can press "Enter", is there a simple way to do it in MVVM?

You said: "I want that when I press Enter on my keyboard this will trigger a button command"
Have you tried adding InputBindings to the text box?
<TextBox.InputBindings>
<KeyBinding Key="Return" Command="{Binding YourCommand}" CommandParameter="{Binding Path=Text, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"/>
</TextBox.InputBindings>

Related

WPF modal dialog on touch screen

I am using a custom modal dialog in a WPF application, that will run on a touch device (Windows 10). I am using the MVVM pattern.
My problem:
I experience different touch behavior depending on from where the dialog is opened. If it is opened from, for example, a button event handler or via button command binding, everything works fine. Then dialog buttons (typically "OK" and "Cancel") closes the dialog on first touch. But when the dialog is opened from code (not driven by button event or button command binding), the dialog buttons does not respond on the first touch. I then need to touch somewhere in the dialog before touching the button. It is kind of annoying.
I have a view model with an ExitCommand implemented that opens the dialog. Some XAML examples:
This works fine:
<Button Content="Exit" Command="{Binding ExitCommand}"/>
This does not work satisfactory:
<Label Content="Exit">
<Label.InputBindings>
<MouseBinding Gesture="LeftClick" Command="{Binding ExitCommand}"/>
</Label.InputBindings>
</Label>
And as mentioned, opening the dialog from code without any user action, does not work either.
Clues, anyone?
I'm not sure that this solution will solve your problem but try this please:
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
<Label Content="Exit">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDown">
<!-- MouseDown trigger for touch down too. -->
<i:InvokeCommandAction Command="{Binding ExitCommand}"
x:Name="exitCommandMouse" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Label>
I use a similar solution with grid (instead label) and its works perfectly with touch screen on win 8.1.

WPF combobox like popup

I am trying to make a custom popup that will be similar to the combobox one.
I used a Toggle button as the header and a Popup for the content.
<ToggleButton IsChecked="{Binding ElementName=Popup, Path=IsOpen, Mode=TwoWay}">
...
</ToggleButton>
<Popup x:Name="Popup" StaysOpen="False">
...
</Popup>
This works great except one case. When the popup is opened and I click on the ToggleButton again, the popup disappears but then reopens right after.
Looks like when I clicked on the toggle button, Popup detected that the mouse click is outside of the popup so it closes itself and sets ToggleButton.IsChecked = false. Then the click sets IsChecked = true so the popup opens again.
Edit: In such case I would like the popup to close just like the behavior of a Combobox.
Is there a way to solve this problem?
Locate the popup on top of the button so the user can't click on the button. You can do it easily with Placement and so on.

Remove WPF IsDefault

I have 3 conrtols placed on my Window in WPF, each control contains one or more TextBox and Button, when a new control is selected I would like to change the IsDefault to that button. What I am currently doing is when the TextBox's GotFocus event is fired, I change my Button to IsDefault. This works the first time but when I change from one control to another, and back to the first selected control the second controls IsDefault is still true and when enter is pressed it fires the Click event on the incorrect control.
Is there a way that i can clear all IsDefault properties on my window or what is a better solution to my current way of doing this? See image below for example, when enter is pressed the Button with "..." is fired instead of quick search.
XAML (Update)
<odc:OdcTextBox Text="{Binding AccountNumber, UpdateSourceTrigger=PropertyChanged}" MinWidth="100" Name="txtAccountNumber" Grid.Row="1" Grid.Column="1" VerticalAlignment="Center" Margin="{Binding TextMargin}">
<odc:OdcTextBox.Buttons>
<Button IsDefault="{Binding ElementName=txtAccountNumber, Path=IsKeyboardFocusWithin}" Width="30" Style="{StaticResource DionysusButton}" x:Name="btnCdv" Content="...">
</Button>
</odc:OdcTextBox.Buttons>
</odc:OdcTextBox>
<Button IsDefault={Binding IsKeyboardFocusWithin, ElementName=ThisGroupBox} />
EDIT:
Your code is slightly different in that you are providing buttons to some custom control. These buttons are declared in a different scope to where they end up (ie I assume they end up inside the OdcTextBox template somewhere). I suspect this is why WPF can't find the named element since that element is named in an outer scope.
You could try using RelativeSource to find the parent OdcTextBox instead:
<Button IsDefault="{Binding IsKeyboardFocusWithin, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type odc:OdcTextBox}}}"
Width="30" Style="{StaticResource DionysusButton}" x:Name="btnCdv" Content="...">
Similarly to how you're using the TextBox GotFocus event, you could do the inverse of this and use the LostFocus event to reset the IsDefault Property

TabItem - show popup on hover

I have a TabControl with multiple TabItems, with each TabItem containing multiple sections in the content area. When the user hovers over any Tab, I'd like to show a Popup that shows a list of the sections in that Tab and allow the user to click on the section and navigate to it.
For this question, the portion that I need help with is the closing/opening of the Popups as the user hovers over each Tab. The main sticking points are:
Allowing the user to move the cursor into the Popup area from the Tab. Once the Popup has been opened, it refuses to close on TabItem MouseLeave.
If the user moves from Tab to Tab, the Popup from the previous Tab should close and a new one should open.
The user should only need one click to navigate. This means they shouldn't have to "click away" the popup from one tab in order for another popup to show.
My thought is to expose a DependencyProperty that hit tests which Tab the mouse is over, and trigger the Popup off of that.
Edited for clarity: When moving the mouse over a tab, I show a popup. When I move the mouse away from the Tab, I want the Popup to go close. It has to be a Popup (and not a Tooltip), because the user has to be able to click on the content inside the Popup.
I've sub-classed and re-templated the TabControl, but I would like some help with how to close the Popup on the MouseLeave event. I've triggered on the MouseLeave event, but when the Popup opens, the focus shifts to the Popup so the TabItem MouseLeave event isn't fired properly.
You can use the Interaction.Triggers from the Blend SDK to trigger the popup to close whenever the mouse leaves the popup. Here is a short example:
<Popup Height="300" x:Name="MyPopup">
<Label Content="MyLabel"></Label>
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeave">
<ei:ChangePropertyAction TargetObject="{Binding ElementName=MyPopup}" PropertyName="IsOpen" Value="False"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Popup>
You'll need the following namespaces:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

UserControl.InputBindings handles mouse event - surrounding listbox item is not selected

I have a user controled defined in my view:
<UserControl.InputBindings>
<MouseBinding Command="{Binding MyCommand}" MouseAction="LeftClick" />
</UserControl.InputBindings>
This UserControl is rendered inside a listbox item.
When I click my user control, the command should be executed, but the listbox item should also get selected. I believe it's caused by the fact that the mousebinding handles my leftclick event, so the listbox will never get it.
Is there a way to accomplish this? I don't want to use code behind on my view.

Categories