In WPF MVVM environment, I'm trying to ensure that focus is given to a TextBox. What happens is that the Cursor appears in the TextBox but is not flashing and the TextBox does not have focus. The code is:
I have a Popup containing this UserControl:
<UserControl x:Class="Rendevous.BusinessModules.AdministrationModule.LogonView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="100" d:DesignWidth="300"
xmlns:my="clr-namespace:Csla.Xaml;assembly=Csla.Xaml"
xmlns:ViewModels="clr-namespace:Rendevous.Common.ViewModels;assembly=Common"
Visibility="{Binding Path=IsViewVisible}"
FocusManager.FocusedElement="{Binding Path=passCodeTextBox}"
ViewModels:FocusExtension.IsFocused="{Binding IsPassCodeFocused}">
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Content="Pass Code:"
VerticalAlignment="Center" />
<TextBox Grid.Column="1" Name="passCodeTextBox" Width="100"
VerticalAlignment="Center"
Margin="3"
Text="{Binding Path=PassCode, UpdateSourceTrigger=PropertyChanged}"
ViewModels:FocusExtension.IsFocused="{Binding IsPassCodeFocused}" />
<Button Grid.Column="2" VerticalAlignment="Center" Margin="3" Name="loginButton"
Content="Log In" />
<Button Grid.Column="3"
VerticalAlignment="Center"
Margin="3"
Name="cancelButton"
Content="Cancel" />
</Grid>
(I've removed some Button handling stuff!)
In my ViewModel, I have code like:
public void LogonButtonClicked(object sender, ExecuteEventArgs e)
{
if (securityService.Login(PassCode))
{
eventBroker.Invoke(EventName.CloseLogonView, this);
}
else
{
IsViewVisible = Visibility.Hidden;
msgService.ShowError("Pass Code was not recognised", "Logon Error");
IsViewVisible = Visibility.Visible;
PassCode = "";
IsPassCodeFocused = true;
}
}
I am using an attached property:
public class FocusExtension
{
public static readonly DependencyProperty IsFocusedProperty = DependencyProperty.RegisterAttached("IsFocused", typeof(bool?), typeof(FocusExtension), new FrameworkPropertyMetadata(IsFocusedChanged));
public static bool? GetIsFocused(DependencyObject element)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
return (bool?)element.GetValue(IsFocusedProperty);
}
public static void SetIsFocused(DependencyObject element, bool? value)
{
if (element == null)
{
throw new ArgumentNullException("element");
}
element.SetValue(IsFocusedProperty, value);
}
private static void IsFocusedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
FrameworkElement fe = (FrameworkElement)d;
if (e.OldValue == null)
{
fe.GotFocus += FrameworkElement_GotFocus;
fe.LostFocus += FrameworkElement_LostFocus;
}
if ((bool)e.NewValue)
{
fe.Focus();
}
}
private 开发者_如何学编程static void FrameworkElement_GotFocus(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).SetValue(IsFocusedProperty, true);
}
private static void FrameworkElement_LostFocus(object sender, RoutedEventArgs e)
{
((FrameworkElement)sender).SetValue(IsFocusedProperty, false);
}
}
}
What happens is that the cursor appears in the TextBox but is not flashing. The TextBox does not have focus because nothing appears when you type. If you click on it, it works fine.
What have I done wrong?
I couldn't reproduce it using the code you provided, but two things I noticed are:
1) On LogonView, I think your intent was
FocusManager.FocusedElement="{Binding ElementName=passCodeTextBox}"
and not
FocusManager.FocusedElement="{Binding Path=passCodeTextBox}"
2) It looks like IsFocused is applied in multiple places. I'd try setting a breakpoint in IsFocusedChanged() and see which control gets it last.
Between that, and watching FocusManager.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.focusedelement.aspx ) and Keyboard.FocusedElement ( http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement ) you should be able to track down where focus is really going.
精彩评论