Remove select all from combobox WPF - wpf

I have combobox in WPF application that when the user clicks on it, it selects all the text. How can I change the behavior of this to when the user clicks it just set the typing cursor like a normal textbox?

Try
<ComboBox IsEditable="True" />

According to Reflector, the ComboBox code contains this:
private static void OnGotFocus(object sender, RoutedEventArgs e)
{
ComboBox box = (ComboBox) sender;
if ((!e.Handled && box.IsEditable) && (box.EditableTextBoxSite != null))
{
if (e.OriginalSource == box)
{
box.EditableTextBoxSite.Focus();
e.Handled = true;
}
else if (e.OriginalSource == box.EditableTextBoxSite)
{
box.EditableTextBoxSite.SelectAll(); // <==
}
}
}
This method is registered for the GotFocus event in the static constructor using the EventManager:
EventManager.RegisterClassHandler(typeof(ComboBox), UIElement.GotFocusEvent, new RoutedEventHandler(ComboBox.OnGotFocus));
So, I think you can only change that behavior by deriving a custom control from ComboBox and override this event registration by your own method which replaces the call to SelectAll() with another method which sets the caret to the correct position. However, I do not know how to set the caret to the click position. You might have to use Reflector on the TextBox to find that...

Seems that I had to solve similar issue.
It's quite tricky, but the way I solved is to set IsEditable to false/true from code, at the same time I set the focus on TextBox.
Not the pretties way but does the job.

Related

Control does not focus

I have a WPF user control with multiple child controls and I am focusing DataGrid and TextBox programmatically with the following code:
searchTextBox.Focus();
and
productGrid.Focus();
productGrid.Focus(dataGrid); //tried this but it does not help
searchTextBox focuses normally but dataGrid does not (keyboard focus stays on some other control). Below I provided full source code that hides searchTextBox and moves focus to productGrid (searchPanel is a parent Grid of searchTextBox):
private void Execute_CancelCommand(object sender, ExecutedRoutedEventArgs e)
{
if (searchPanel.Visibility == Visibility.Visible)
{
searchPanel.Visibility = Visibility.Collapsed;
searchTextBox.Clear();
searchTextBox.Background = Brushes.White;
//the focus stays on the splitter for some reason
productGrid.Focus();
Keyboard.Focus(productGrid);
}
}
what can cause this situation?
Thnx.
It seems that productGrid.Focusable property is set to "false". You should just set it to "True" and your code should work correctly and there will be no need in calling Keyboard.Focus() method.

WPF popup listbox use keyboard for navigation

Can anyone suggest the solution how can I make navigation using down and up keys in listbox which come on popup.
Solutions like set selected items on keyup and keydown event are not working for me.
Should I make something more special then just set selected item in this case?
ListBox already implements selection navigation using keyboard when it is focused.
All you have to do is give it focus when you want, for example in the window that contains it:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down)
{
listbox.SelectedIndex = 0;
listbox.Focus();
}
}
Because listbox.Focus(); will only give it focus but won't yet change the selection item (which will make the user hit's the "Down" button twice in order to do so) set the ListBox's SelectedIndex first.
Hope this helps

Setting Default Keyboard Focus On Loading A UserControl

I have an MVVM setup with a mainwindow that contains a ContentControl.
I set this to a particular viewmodel which then maps to a view.
A view is a usercontrol.
I want to be able to set the default keyboard focus to a default element in the usercontrol(View) when it loads so the application can eventually be driven just by using up, down, left, right and enter.
Some of my failed attempts are setting
FocusManager.FocusedElement="{Binding ElementName=DefaultElement}"
in my content control tag. This sets the logical focus but not the keyboard focus
I'd rather keep the solution in xaml if possable but have tried placing the following in code behind.
Keyboard.Focus(DefaultElement);
This does not work but if I popup a message box first it does. I'm a little confused as to why.
MessageBox.Show(Keyboard.FocusedElement.ToString());
Keyboard.Focus(DefaultElement);
EDIT::::
I just placed this in my onloaded event of my user control. It seems to work but can anyone see any issues that might arrise at this priority level. I.E a circumstance when the action will never run?
Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(delegate()
{
Keyboard.Focus(DefaultElement);
}));
It seems that this wpf the you have to implement a workaround on a case by case basis. The solution that seemed to work best, most of the time for me was to insert the focus code inside the dispatcher when OnVisible was changed. This sets the focus not only when the View/Usercontrol loads but also if you a changing Views by way of Visibility. If you Hide and then Show a ContentControl that is mapped to your ViewModels then the Loaded event won't fire and you'll be forced to Mouse input, or tabbing (Not so good if you want to navigate your app with a remote control).
VisibilityChanged will always fire however. This is what I ended up with for my listbox.
private void ItemsFlowListBox_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if ((bool)e.NewValue == true)
{
Dispatcher.BeginInvoke(
DispatcherPriority.ContextIdle,
new Action(delegate()
{
ItemsFlowListBox.Focus();
ItemsFlowListBox.ScrollIntoView(ItemsFlowListBox.SelectedItem);
}));
}
}
I had the same symptom for a WPF UserControl hosted in a Winforms application. Just wanted to note I was about to try this solution when I found a normal TabIndex in the Winforms app fixed it
Per How to set which control gets the focus on application start
"The one with the minimum tab index automatically gets the focus
(assuming the TabStop property is set to true). Just set the tab
indices appropriately."
It's a tricky one with no easy answer. I'm currently doing this, although I'm not sure I like it:
public MyView()
{
InitializeComponent();
// When DataContext changes hook the txtName.TextChanged event so we can give it initial focus
DataContextChanged +=
(sender, args) =>
{
txtName.TextChanged += OnTxtNameOnTextChanged;
};
}
private void OnTxtNameOnTextChanged(object o, TextChangedEventArgs eventArgs)
{
// Setting focus will select all text in the TextBox due to the global class handler on TextBox
txtName.Focus();
// Now unhook the event handler, since it's no longer required
txtName.TextChanged -= OnTxtNameOnTextChanged;
}
And in case you're wondering what the global class handler does, it's this:
protected override void OnStartup(StartupEventArgs e)
{
...
// Register a global handler for this app-domain to select all text in a textBox when
// the textBox receives keyboard focus.
EventManager.RegisterClassHandler(
typeof (TextBox), UIElement.GotKeyboardFocusEvent,
new RoutedEventHandler((sender, args) => ((TextBox) sender).SelectAll()));
which auto selects TextBox text when receiving keyboard focus.

WPF ComboBox, force input to UpperCase

I have an editable WPF ComboBox with TextSearchEnabled. I need to force the user's text input to uppercase when they type to filter the ComboBox.
I was thinking of modifying the textbox that is part of the control (named 'PART_EditableTextBox') to set CharacterCasing="Upper", however I can't quite figure out how to do this.
Do I need to use a trigger, or modify the template in some way?
This works and seems like a reasonable solution:
protected void winSurveyScreen_Loaded(object sender, RoutedEventArgs e)
{
(comboBox.Template.FindName("PART_EditableTextBox", cbObservation) as TextBox).CharacterCasing = CharacterCasing.Upper;
}
Ensure that the combobox is not collapsed on loaded otherwise the template will not be found.
IMO, the quicker way is to set the UpdateTrigger to PropertyChanged and, in the data object, uppercase the value when it is updated.
I found that post where the attached property is used. That permit to use that for all of your ComboBox without rewriting the code.
private void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
Textbox editableTextbox = sender as Textbox;
foreach (char ch in e.Text)
{
if (Char.IsLower(ch))
{
editableTextbox.Text += Char.ToUpper(ch);
e.Handled = true;
}
}
}
or try creating an attached behaviour for the textbox

WPF: Changes to textbox with focus aren't committed until after the Closing event fires

I have a WPF window for editing database information, which is represented using an Entity Framework object. When the user closes the window, I'd like to notice in the Closing event whether the information has changed and show a message box offering to save the changes to the database.
Unfortunately, changes to the currently focused edit aren't assigned to the binding source until the edit loses focus, which happens at some point after the Closing event has been processed.
Ideally, there would be a routine which commits all changes in the view hierarchy that I could call before checking to see if my entity has been modified. I've also looked for information on programmatically clearing the focus in the control with focus, but can't figure out how to do it.
My question is, how is this typically handled?
In WPF you can change a Binding to update the source on modification, rather than on losing the focus. This is done by setting the UpdateSourceTrigger property to PropertyChanged:
Value="{Binding Path=MyProperty, UpdateSourceTrigger=PropertyChanged}"
This should get you pretty close:
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
ForceDataValidation();
}
private static void ForceDataValidation()
{
TextBox textBox = Keyboard.FocusedElement as TextBox;
if (textBox != null)
{
BindingExpression be = textBox.GetBindingExpression(TextBox.TextProperty);
if (be != null && !textBox.IsReadOnly && textBox.IsEnabled)
{
be.UpdateSource();
}
}
}
Maybe you need to remove the focus from the current element
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
FocusManager.SetFocusedElement(this, null);
}
Assuming that there is more than one control in the tab sequence, the following solution appears to be complete and general (just cut-and-paste)...
Control currentControl = System.Windows.Input.Keyboard.FocusedElement as Control;
if (currentControl != null)
{
// Force focus away from the current control to update its binding source.
currentControl.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
currentControl.Focus();
}
Also look at the sugestions in this post
The easiest way is to set the focus somewhere.
You can set the focus back immediately, but setting the focus anywhere will trigger the LostFocus-Event on any type of control and make it update its stuff:
IInputElement x = System.Windows.Input.Keyboard.FocusedElement;
DummyField.Focus();
x.Focus();
Another way would be to get the focused element, get the binding element from the focused element, and trigger the update manually. An example for TextBox and ComboBox (you would need to add any control type you need to support):
TextBox t = Keyboard.FocusedElement as TextBox;
if ((t != null) && (t.GetBindingExpression(TextBox.TextProperty) != null))
t.GetBindingExpression(TextBox.TextProperty).UpdateSource();
ComboBox c = Keyboard.FocusedElement as ComboBox;
if ((c != null) && (c.GetBindingExpression(ComboBox.TextProperty) != null))
c.GetBindingExpression(ComboBox.TextProperty).UpdateSource();

Resources