我正在实现类似自动提示控制的东西:我有一个包含TextBox
和ListBox
的用户控件。当用户输入文字时,我会使用System.Windows.Interactivity
行为进行处理,并使用某些值填充ListBox
...
一切正常......但我想让用户在按下向下箭头键时选择ListBox
中的项目(即在Focus
上设置ListBox
)
我知道可以在代码隐藏的.cs文件中处理KeyPressDown
的{{1}}事件但是我该如何避免这种情况?
答案 0 :(得分:5)
如果您已经使用了不应该成为问题的交互,那么只需实施自己的TriggerAction
,其属性为Key
& TargetName
来确定何时以及要关注什么。将其设置为EventTrigger
的{{1}}。
示例实施&使用方法:
PreviewKeyDown
<TextBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewKeyDown">
<t:KeyDownFocusAction Key="Down"
Target="{Binding ElementName=lbx}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<ListBox Name="lbx" ItemsSource="{Binding Data}" />
测试它并且它有效,请注意class KeyDownFocusAction : TriggerAction<UIElement>
{
public static readonly DependencyProperty KeyProperty =
DependencyProperty.Register("Key", typeof(Key), typeof(KeyDownFocusAction));
public Key Key
{
get { return (Key)GetValue(KeyProperty); }
set { SetValue(KeyProperty, value); }
}
public static readonly DependencyProperty TargetProperty =
DependencyProperty.Register("Target", typeof(UIElement), typeof(KeyDownFocusAction), new UIPropertyMetadata(null));
public UIElement Target
{
get { return (UIElement)GetValue(TargetProperty); }
set { SetValue(TargetProperty, value); }
}
protected override void Invoke(object parameter)
{
if (Keyboard.IsKeyDown(Key))
{
Target.Focus();
}
}
}
没有,因为箭头键被拦截并标记为由TextBox处理。
答案 1 :(得分:3)
我认为你不能避免它
捕获TextBox的KeyDown
事件有什么问题,如果它是向上或向下箭头键,只需在后面的代码中触发ListBox.KeyDown
事件?
我认为没有理由不在MVVM中使用代码隐藏,如果要提供特定于视图的功能,例如焦点
答案 2 :(得分:0)
此答案基于H.B.
中的答案,并添加了对检查是否按下Ctrl键的支持。这意味着它可以处理键组合,例如Ctrl-F for find。
<TextBox>
<i:Interaction.Triggers>
<i:EventTrigger EventName="PreviewKeyDown">
<t:KeyDownFocusAction Key="Down" Ctrl="True"
Target="{Binding ElementName=lbx}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<ListBox Name="lbx" ItemsSource="{Binding Data}" />
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
请参阅help on adding System.Windows.Interactivity
。
public class KeyDownFocusAction : TriggerAction<UIElement>
{
public static readonly DependencyProperty KeyProperty =
DependencyProperty.Register("Key", typeof(Key), typeof(KeyDownFocusAction));
public Key Key
{
get { return (Key)GetValue(KeyProperty); }
set { SetValue(KeyProperty, value); }
}
public static readonly DependencyProperty CtrlProperty =
DependencyProperty.Register("Ctrl", typeof(bool), typeof(KeyDownFocusAction));
public bool Ctrl
{
get { return (bool)GetValue(CtrlProperty); }
set { SetValue(CtrlProperty, value); }
}
public static readonly DependencyProperty TargetProperty =
DependencyProperty.Register("Target", typeof(UIElement), typeof(KeyDownFocusAction), new UIPropertyMetadata(null));
public UIElement Target
{
get { return (UIElement)GetValue(TargetProperty); }
set { SetValue(TargetProperty, value); }
}
protected override void Invoke(object parameter)
{
if (Keyboard.IsKeyDown(Key))
{
if (Ctrl == true)
{
if (Keyboard.IsKeyDown(Key.LeftCtrl) || Keyboard.IsKeyDown(Key.RightCtrl))
{
Target.Focus();
}
}
}
}
}