Reputation: 63
I have a dialog with few controls. There is a TextBox
named txtControl and two Buttons
Accept and Cancel. I want that once the focus is in txtControl, the focus should not go away, until I click on Accept or Cancel button.
If I try to click on any other control without clicking on Accept or Cancel button, then focus should remains in txtControl. Also I don't want to disable or gray out other controls.
Upvotes: 0
Views: 558
Reputation: 2133
You might handle OnPreviewMouseDown in the root, whenever focus is on txtControl, and the mouse is not over txtControl, Accept or Cancel;
void mainWindow_previewMouseDown(object sender, MouseEventArg e)
{
if (txtControl.IsFocusWithin)
{
if (txtControl.IsMouseOver == false ||
accept.IsMouseOver ==false ||
cancel.IsMouseOver ==false)
{
e.Handle = true;
}
}
}
and you might also hadle PreviewKeyDown to see if Tab is Pressed or not.
Upvotes: 1
Reputation: 6466
I would create an attached property that looked for the textbox losing Keyboad focus and just force focus back in to the textbox again.
The attached property would be something like this.
public class TextBoxExtras : DependencyObject
{
public static bool GetRetainsFocus(DependencyObject obj)
{
return (bool)obj.GetValue(RetainsFocusProperty);
}
public static void SetRetainsFocus(DependencyObject obj, bool value)
{
obj.SetValue(RetainsFocusProperty, value);
}
public static readonly DependencyProperty RetainsFocusProperty =
DependencyProperty.RegisterAttached("RetainsFocus", typeof(bool), typeof(TextBoxExtras), new PropertyMetadata(false, new PropertyChangedCallback((s, e) =>
{
TextBox textBox = s as TextBox;
if (textBox != null)
{
if (!(bool)e.NewValue && (bool)e.OldValue)
textBox.LostKeyboardFocus -= textBox_LostKeyboardFocus;
if ((bool)e.NewValue)
{
textBox.LostKeyboardFocus += textBox_LostKeyboardFocus;
textBox.Unloaded += textBox_Unloaded;
}
}
})));
static void textBox_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null )
if (textBox.Focusable)
textBox.Focus();
}
static void textBox_Unloaded(object sender, RoutedEventArgs e)
{
TextBox textBox = sender as TextBox;
if (textBox != null)
{
textBox.LostKeyboardFocus -= textBox_LostKeyboardFocus;
textBox.Unloaded -= textBox_Unloaded;
}
}
}
And use it in XAML like this, the first textbox is the one that will "retain focus"
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication4"
Background="Black"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox local:TextBoxExtras.RetainsFocus="True" Margin="10,10,387,283"/>
<TextBox HorizontalAlignment="Left" Height="23" Margin="10,37,0,260" Width="120" />
<Button Content="Accept" HorizontalAlignment="Left" Margin="10,81,0,0" VerticalAlignment="Top" Width="75" />
</Grid>
</Window>
Upvotes: 0
Reputation: 11906
You could handle the PreviewLostKeyboardFocus at root level.
In xaml
<Window ... PreviewLostKeyboardFocus="Win_PreviewLostKeyboardFocus">
In C#
private void Win_PreviewLostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
// change focus behavior only when txtControl
// is the element losing focus
if (e.OldFocus != txtControl)
return;
// if new element with focus is not Accept and is not Cancel, then disable the focus change
if (e.NewFocus != Accept && e.NewFocus != Cancel)
e.Handled = true;
}
Upvotes: 0
Reputation: 4546
This kind of restriction is not a good idea.
How will your app be used by someone who can't use a mouse and uses the tab key to move between controls?
Upvotes: 0