Up/down key bindings not recognized - wpf

I have a textbox and a listbox. The listbox shows search suggestions for the textbox.
I want to highlight the first listbox item when user presses down arrow when the textbox is focused.
Similarly, the textbox should be focused back when the user is as the first element on the listbox and presses the up arrow.
I am using the following code for KeyBindings:
<KeyBinding Key="Down" Command="{x:Static local:SearchView.ApplicationShortCutsCommand}" CommandParameter="{x:Static common:SearchViewCommands.MoveToSuggestions}" />
<KeyBinding Key="Up" Command="{x:Static local:SearchView.ApplicationShortCutsCommand}" CommandParameter="{x:Static common:SearchViewCommands.MoveToQuery}" />
Other keys such as Esc and Enter work fine, although this one doesn't work at all (the associated event isn't fired).
Any suggestions?

The events associated with ListBox up and down have priority.
I ended up using shift up/down instead because there are so many event consumers that use the up and down events.

Related

How to get the selected name,value from WPFAutoComplete:TextBoxAutoCompleteProvider event?

I am new to XAML forms. I have some code written years ago by another programmer which I now need to modify. I am trying to intercept the selection that is applied to the textbox when the user presses enter or clicks the mouse on a selection from the dropdown list.
<TextBox x:Name="txtVendor" HorizontalAlignment="Left" Height="23" Margin="24,299,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="250"/>
<WPFAutoComplete:TextBoxAutoCompleteProvider x:Name="txtVendorAuto" DisplayMemberPath="Name" SelectedValuePath="VendorNumber" HorizontalAlignment="Left" Height="100" Margin="24,322,0,0" VerticalAlignment="Top" Width="250" TargetControl="{Binding ElementName=txtVendor}" MaxResults="20" MinWidth="250" MinTypedCharacters="2"/>
I thought it would be similar to C#/Vb code in that I would check the selected index change event and get the values, however the only event that looks close is the "SelectionChanged" which fires with any text input and not the actual selected item. I managed to check for the keydown event in the textbox and look for the enter key and that seems to work, but I cannot determine when someone has selected something via the mouse. I have checked the various mouse events (left mouse button down,up, etc.)
Is there a way to simply get the item from the search when it is selected (keyboard or mouse)?

WPF bind a control visibility to the focused property of another control

I have a combobox that displays a list of items, and I want to place a button next to it which triggers a command to see the details of the selected item. So far, so good. Now I want the button to be visible only if the combobox has focus (or is in "edit" mode, but not only when the popup is open).
I thought I could bind the visibility of the button to some focus property of the combobox, something like this:
<Button Content="Details" Visibility="{Binding ElementName=elementListComboBox,
Path=IsFocused, Converter={StaticResource Bool2VisibilityConverter}}"/>
But I found no way to know if the control I want is focused or not. I looked at the FocusManager.FocusedElement, but I don't know how to get the focused control I want inside the binding. Is there a way to achieve this in XAML?
Ok, the way to get this working as I wanted is this:
<Button Command="{Binding SomeCommand}"
Content="Details"
Focusable="False"
Visibility="{Binding ElementName=elementListComboBox,
Path=IsKeyboardFocusWithin,
Converter={StaticResource Bool2VisibilityConverter}}"/>
Two key factors here: bind the button's visibility to IsKeyboardFocusWithin property of the combobox, and set the button's Focusable property to false, else it will get collapsed when you want to click on it.
Hope this is useful.

how to bind input key to itemscontrol in wpf

I have an items control which has items on a canvas, when I press delete I want to delete an item from the canvas:
<ItemsControl.InputBindings>
<KeyBinding Command="{Binding DeleteItemCommand}" Key="Delete"/>
</ItemsControl.InputBindings>
However, the method in DeleteItemCommand is never called.
How can I achieve this?
The ItemsControl (or possibly something within) needs to be Focusable to receive keyboard input.

How to set logical focus without giving keyboard focus?

How can I in code define the logical focus of a container, or focused child, WITHOUT giving it keyboard focus ?
I just want to control which child will get the focus when the control will get focus through Tab key or clicking on part of the container that does not hit a child, but not give it (or steal) actual focus if it doesn't already have it.
And I also want that selecting a specific child through a keyboard gesture or clicking on it with the mouse is still possible.
I understand the difference in WPF between Keyboard Focus and Logical Focus, and the fact that for an element, having Keyboard Focus implies also having logical focus, but having logical focus does not imply that the element have keyboard focus.
I also understand attached property FocusManager.FocusedElement defines which element has logical focus in the visual tree starting at the element defining this property.
I’ve realized that this property is not used only when FocusManager.IsFocusScope is set to true, but also for containers such as GroupBox.
I’ve made many attempts, tons of searches and reading on WPF focus topic, but with no success so far, I don't understand what I'm missing:
Calling FocusManager.SetFocusedElement also give keyboard focus, and it I temporarily change the property Focusable of my child element to false just before, it only works the very first time when no child had focus before, but not after a child got focus
Handling events GotKeyboardFocus and PreviewGotKeyboardFocus at element or container to override initial focused element doesn’t work either, since I cannot tell whether the focus was obtained through the mouse or the keyboard, and whether focus got directly set to a child element or indirectly through the container.
An example to illustrate what I’m trying to achieve: I’ve a simple group of RadioButtons, and I want to control dynamically in code which option will get focus when user will “tab” to move focus to this GroupBox (typically the option that has isChecked=true).
<GroupBox Header="Options" Name="myGroupBox"
KeyboardNavigation.TabNavigation="Once"
KeyboardNavigation. DirectionalNavigation="Cycle" >
<StackPanel>
<RadioButton GroupName="g1" Name="opt1" Content="Option _1"/>
<RadioButton GroupName="g1" Name="opt2" Content="Option _2"/>
<RadioButton GroupName="g1" Name="opt3" Content="Option _3"/>
</StackPanel>
</GroupBox>
A final comment, I know how to implement a dynamic list of options using a ListBox, binding selectedItem of the list to a property of the data context, and then through styles and templates on ListBoxItem bind IsChecked property of the RadioButton in item template to IsSelcted property of its parent ListBoxItem, and it works, but for my specific case, I need to keep my RadioButtons directly bound to properties of my data context, I can’t bind them to IsSelected property of the list at the same time.
I know this is an old question but hopefully this answer will help others with a similar problem.
If I understand the problem correctly, you can achieve the desired behaviour by setting FocusManager.IsFocusScope="True" on the GroupBox, and hook up an event handler for the RadioButton.Checked event that sets the Logical Focus to the sender of the event:
Xaml:
<GroupBox Header="Options" Name="myGroupBox"
FocusManager.IsFocusScope="True"
RadioButton.Checked="MyGroupBox_OnChecked"
KeyboardNavigation.TabNavigation="Once"
KeyboardNavigation.DirectionalNavigation="Cycle">
<StackPanel>
<RadioButton GroupName="g1" Name="opt1" Content="Option _1"/>
<RadioButton GroupName="g1" Name="opt2" Content="Option _2"/>
<RadioButton GroupName="g1" Name="opt3" Content="Option _3"/>
</StackPanel>
</GroupBox>
Code behind:
private void MyGroupBox_OnChecked(object sender, RoutedEventArgs e)
{
var radioB = sender as RadioButton;
if (radioB != null)
FocusManager.SetFocusedElement(myGroupBox, radioB);
}
As the Document remarked, FocusManager.SetFocusedElement will give the specified element logical focus in the specified focus scope and will attempt to give the element keyboard focus.
I encountered the same problem, and I feel this attempt to give the element keyboard focus is rather not predictable. In some cases, the element which gets the logical focus will also get the keyboard focus. But in some other cases, it won't. I have not yet figured out the exact mechanism behind.
If the official documents say so, I reckon there may not be an "official" way to implement what you want. For now I am doing this by just invoking Keyboard.Focus upon the element you would like to maintain the keyboard focus after setting the logical focus.
An illustration of what I am explaining is as follows:
private void SomeMember(){
FocusManager.SetFocusedElement(focusScope, logicalFocus);
Keyboard.Focus(controlMaintainingKeyboardFocus);
}

WPF Toolkit MaskTextBox Binding Issue

I have a simple control that has a masked text box:
xmlns:extToolkit="http://schemas.microsoft.com/winfx/2006/xaml/presentation/toolkit/extended"
...
<extToolkit:MaskedTextBox Mask="000-000-000" Text="{Binding SerialNumber, UpdateSourceTrigger=PropertyChanged}" />
I also have a key binding on the control:
<UserControl.InputBindings>
<KeyBinding Command="{Binding SearchCommand}" Gesture="Enter" />
</UserControl.InputBindings>
The problem is when SearchCommand is executed I need the value they entered in the masked text box as the criteria for the search. With a regular text box this is no problem but apparently the MaskedTextBox control doesn't play well with PropertyChanged UpdateSourceTrigger.
If I click someplace else (so it looses focus) and then press enter it works, but obviously I don't want to have to do that. Are there any good workarounds for this situation?
You must bind your property to the Value property not the Text.
http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox&referringTitle=Documentation

Resources