2010-06-24 3 views
2

В моем приложении WPF у меня есть элемент управления текстовым полем. Элемент управления текстовым полем находится в UserControl, который, в свою очередь, имеет класс View Model. В моем классе VM у меня есть команда, которая запускается либо при нажатии кнопки в UserControl, либо при нажатии клавиши Enter. Моя проблема в том, что когда я нажимаю Enter, текстовое поле теряет фокус, и я должен щелкнуть по текстовому полю, чтобы снова сфокусировать его. Что я могу сделать, чтобы текстовое поле сохраняло фокус при нажатии клавиши?TextBox теряет фокус на команде клавиш

Я стараюсь сделать набросок того, что я использую сейчас:

<Window> 
    <uc:DesignPanel ... /> 
    <uc:CommandPrompt ... /> 
</Window> 

<UserControl Name=CommandPrompt ...> 
    <StackPanel> 
     <TextBox Name="tb_commands" /> 
     <Button Name="btn_process" FocusManager.FocusedElement="{Binding ElementName=tb_commands}" /> 
    </StackPanel>  
</UserControl> 

управления пользователь Designpanel в свою очередь, содержит другие пользовательские элементы управления (UCOperands). UCOperand в основном выглядит следующим образом:

<UserControl Name="UCOperand" Focusable="true"> 
    <UserControl.InputBindings ... /> 
</UserControl> 

Отметим здесь, что я поставил Focusable = «истина» на UCOperand, это необходимо, потому что в противном случае пользователь не может ссылаться на входные команды, определенные на этом Contrl. Если я удалю это свойство или настрою его на false, то все будет работать так, как я ожидаю, например. когда я нажимаю Enter, когда я редактирую текстовое поле «tb_commands» или нажимаю кнопку «btn_process», фокус сохраняется в текстовом поле. Но, как и сейчас, всякий раз, когда вы нажимаете Enter или нажимаете кнопку, tb_commands теряет фокус.

Заранее спасибо.

ответ

0

Я не уверен, есть ли способ заставить его держать фокус, но вы должны иметь возможность справиться, когда это произойдет, а затем вы можете просто установить фокус обратно на TextBox.

Вот пример MSDN называется How to: Detect When the Enter Key Pressed

Если изменить написание текста в этом образце, чтобы быть yourTextBox.Focus() я бы предположить, что это будет работать.

+0

Проблема заключается в том, что при нажатии клавиши Enter вызывается команда, которая, в свою очередь, добавляет новый UserControl к моей DesignPanel. Событие KeyDown не обрабатывается в коде позади, и хотя я пытался это сделать, он просто не работает, потому что я полагаю, пользовательский элемент управления UCOperand получает фокус после того, как я могу вызвать tb_commands.Focus(), поэтому этот вызов бесполезно в моем случае. – Zoliqa

0

Добавьте раскадровку с короткой продолжительностью в свое окно и используйте событие Completed, чтобы установить фокус на текстовое поле (см. Нижнюю часть моего образца).

<Window x:Class="TextboxFocus.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:uc="clr-namespace:TextboxFocus.Views" 
    KeyDown="Window_KeyDown" 
    Title="Main Window" Height="400" Width="800"> 

    <Window.Triggers> 
     <EventTrigger RoutedEvent="FrameworkElement.Loaded"> 
      <BeginStoryboard> 
       <Storyboard BeginTime="0:0:1" Completed="Go_Completed"> 
       </Storyboard> 
      </BeginStoryboard> 
     </EventTrigger> 
    </Window.Triggers> 
    <DockPanel> 
     <uc:CommandPrompt x:Name="UC" > 
     </uc:CommandPrompt> 
    </DockPanel> 
</Window> 


<UserControl x:Class="TextboxFocus.Views.CommandPrompt" 
    Name="UCOperand" 
    Focusable="true" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Height="300" Width="300"> 
    <Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition/> 
     <RowDefinition/> 
    </Grid.RowDefinitions> 
    <TextBox Grid.Row="0" 
      x:Name="GoTextbox"/> 
    <Button Grid.Row="1" 
     Content="Go" 
     FocusManager.FocusedElement="{Binding ElementName=GoTextbox}" 
     Command="{Binding GoCommand}" /> 
    </Grid> 
</UserControl> 


public partial class MainView : Window 
{ 
    MainViewModel _mvm = new MainViewModel(); 

    public MainView() 
    { 
    InitializeComponent(); 

    this.DataContext = _mvm; 
    } 

    private void Window_KeyDown(object sender, KeyEventArgs e) 
    { 
    // trap the F5/Enter key and execute the query.... 
    if (e.Key == Key.Enter) 
    { 
     _mvm.GoCommand.Execute(null); 
     e.Handled = true; 
    } 
    } 

    // set focus here 
    private void Go_Completed(object sender, EventArgs e) 
    { 
    UC.GoTextbox.Focus(); 
    } 
} 
+0

Спасибо Замбони за ваш ответ, но, к сожалению, это не работает в моем сценарии. Пожалуйста, взгляните на мой первоначальный пост выше, я сделал некоторые изменения на нем, чтобы немного уточнить проблему. – Zoliqa

+0

Спасибо за редактирование сообщения. Я изменил свой ответ, надеюсь, что это поможет. – Zamboni

+0

Я пробовал ваш подход, но он, похоже, не помогает мне. Основная проблема, по-моему, заключается в добавлении пользовательских элементов управления в DesignPanel. Таким образом, когда пользователь нажимает кнопку «btn_process», в результате новый элемент управления добавляется в DesignPanel, который, вероятно, берет фокус из моего текстового поля и места на вновь созданном пользовательском элементе управления, UCOperand, который имеет Focusable = «true "набор свойств. Как я уже сказал, если я удалю этот установщик свойств, тогда все в порядке, но это не вариант для меня. – Zoliqa

Смежные вопросы