WPF和MVVM:如何自动将焦点转移到下一个控件
本文关键字:转移 焦点 下一个 控件 何自动 MVVM WPF | 更新日期: 2023-09-27 17:57:56
我有一个小的WPF窗口,其中有2个TextBoxes Having Ordered TabIndex 0,1,当我按下Enter键时,我想自动将焦点从第一个TextBox移动到第二个。我使用MVVM Light。
备注:此帖子不重复。在这里,我不使用事件处理程序的经典方法,但MVVM模式和代码隐藏在视图中是不允许的。
我找到了一个解决方案,但我不知道它是否尊重MVVM原则。这里的代码:
查看
<Window x:Class="WpfMMVLight2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd ="http://www.galasoft.ch/mvvmlight"
Title="MainWindow" Height="350" Width="525"
DataContext="{Binding MainViewModel}">
<Grid FocusManager.FocusedElement="{Binding ElementName=tb1}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="70"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="Text 1" VerticalAlignment="Center"/>
<TextBox x:Name="tb1" Grid.Column="1" VerticalAlignment="Center" Margin="5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<cmd:EventToCommand PassEventArgsToCommand="True"
Command ="{Binding KeyDownCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBlock Grid.Column="0" Grid.Row="1" Text="Text 2" VerticalAlignment="Center"/>
<TextBox x:Name="tb2" Grid.Column="1" Grid.Row="1" VerticalAlignment="Center" Margin="5">
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<cmd:EventToCommand PassEventArgsToCommand="True"
Command ="{Binding KeyDownCommand, Mode=OneWay}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
</Grid>
ViewModel:
private ICommand _keydownCommand;
public ICommand KeyDownCommand
{
get
{
if (_keydownCommand== null)
_keydownCommand= new DelegateCommand<KeyEventArgs>(KeyDownCommandExecute);
return _keydownCommand;
}
}
private void KeyDownCommandExecute(KeyEventArgs e)
{
if (e != null && e.Key == Key.Enter)
{
TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next);
request.Wrapped = true;
((Control)e.Source).MoveFocus(request);
}
}
}
我不知道是否允许在ViewModel中使用"Control"类
当您使用MVVM时,您可以为此使用行为:
public class TabOnEnterBehavior : Behavior<TextBox>
{
protected override void OnAttached()
{
AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;
}
private void AssociatedObject_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
var request = new TraversalRequest(FocusNavigationDirection.Next);
request.Wrapped = true;
AssociatedObject.MoveFocus(request);
}
}
protected override void OnDetaching()
{
AssociatedObject.PreviewKeyDown -= AssociatedObject_PreviewKeyDown;
}
}
在您的xaml:中
<TextBox>
<i:Interaction.Behaviors>
<wpfTest:TabOnEnterBehavior />
</i:Interaction.Behaviors>
</TextBox>
首先向TextBox
添加PreviewKeyDown
事件:
<TextBox PreviewKeyDown="OnTextBoxKeyDown" />
然后创建一个TraversalRequest
,将焦点转移到下一个项目:
private void OnTextBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Return)
{
TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Next);
MoveFocus(request);
}
}
编辑
或者,如果您喜欢使用命令,您可以在TextBox
:中设置KeyBinding
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding YourCommand}" />
</TextBox.InputBindings>
只需在ICommand s
执行逻辑中放入与上述内容大致相同的内容。
同样的问题是:当在WPF应用程序中按下Return时,我如何模拟Tab键的按下?