2010-10-20 5 views
2

В среде WPV MVVM я пытаюсь обеспечить, чтобы фокус был задан TextBox. Случается, что курсор появляется в TextBox, но не мигает, а TextBox не имеет фокуса. Код:Фокус на WPF TextBox не работает должным образом с прикрепленными свойствами

У меня есть Popup, содержащий этот 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> 

В моей ViewModel, у меня есть код, как :

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; 
     } 
    } 

Я использую вложенное свойство:

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); 
    } 
} 

}

Что происходит, что появляется курсор в TextBox, но не мигает. TextBox не имеет фокуса, потому что при вводе ничего не появляется. Если вы нажмете на него, он будет работать нормально.

Что я сделал не так?

+0

У меня такая же проблема, даже без привязанности. – RoelF

+0

вы можете увидеть: http://stackoverflow.com/questions/1356045/set-focus-on-textbox-in-wpf-from-view-model-c –

ответ

0

Я не мог воспроизвести его с помощью кода вы предоставили, но две вещи, которые я заметил, являются:

1) На LogonView, я думаю, ваше намерение было

FocusManager.FocusedElement="{Binding ElementName=passCodeTextBox}"

и не

FocusManager.FocusedElement="{Binding Path=passCodeTextBox}"

2) Похоже, что IsFocused применяется в нескольких местах. Я попытался бы установить точку останова в IsFocusedChanged() и посмотреть, какой элемент управления получает последний.

Между тем, и смотреть FocusManager.FocusedElement (http://msdn.microsoft.com/en-us/library/system.windows.input.focusmanager.focusedelement.aspx) и Keyboard.FocusedElement (http://msdn.microsoft.com/en-us/library/system.windows.input.keyboard.focusedelement) вы должны быть в состоянии отследить, где фокус на самом деле происходит.