[英]user control loses keyboard focus
我创建了一个用户控件,我称之为InputTextBox,它提供了用户只有在单击控件后才能编辑的文本:
<Grid>
<TextBox Name="box"
Text="{Binding RelativeSource={RelativeSource AncestorType=local:InputTextBlock}, Path=Text, Mode=TwoWay}"
Visibility="Hidden"
LostKeyboardFocus="box_LostKeyboardFocus"
KeyDown="box_KeyDown"/>
<Button Name="block"
Background="Transparent"
BorderThickness="0"
Click="block_Click">
<Button.Content>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=local:InputTextBlock}, Path=Text}" />
</Button.Content>
</Button>
</Grid>
当用户单击该按钮时,使用以下callack:
private void block_Click(object sender, RoutedEventArgs e)
{
StartEdit();
}
public void StartEdit()
{
box.Visibility = Visibility.Visible;
block.Visibility = Visibility.Hidden;
box.CaretIndex = box.Text.Length;
Keyboard.Focus(box);
}
在控件中处理两个更重要的事件。 第一个是控件失去键盘焦点时:
private void box_LostKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
{
box.Visibility = Visibility.Hidden;
block.Visibility = Visibility.Visible;
}
另一种是当用户按下TAB或ENTER键时:
private void box_KeyDown(object sender, KeyEventArgs e)
{
Key key = e.Key;
if (key == Key.Enter || key == Key.Tab)
{
RoutedEventArgs args = new RoutedEventArgs(KeyExitEvent, this, e.Key);
RaiseEvent(args);
}
}
这引发了我为此控件注册的名为KeyExit的简单路由事件。
所以,基本上,就像这个控件有两个“模式”:用户可以通过简单地点击控件来激活的“编辑模式”,以及用户可以通过在UI中提供任何其他控件来返回的“查看模式”键盘焦点。
在我的UI中,我有一个堆栈面板,其中包含一堆这些控件 - 每个控件都包含在我创建的类中,与ListViewItem的概念类似。 这个想法是当用户在堆栈面板中的一个项目内处于编辑模式并单击TAB或ENTER键时,面板中的下一个控件将进入编辑模式。
所以,我有以下事件回调:
private void item_KeyExit(object sender, RoutedEventArgs e)
{
FrameworkElement obj = e.OriginalSource as FrameworkElement;
if (obj != null)
{
var listItem = VisualTreeHelperUtils.FindFirstAncestorOfType<MyListItem>(obj);
if (listItem != null)
{
int itemIndex = stackPanelList.Children.IndexOf(listItem);
MyListItem nextItem = null;
if (itemIndex == ucSortableList.Children.Count - 1)
{
nextItem = stackPanelList.Children[itemIndex+1] as MyListItem;
}
if (nextItem != null)
{
var item = nextItem.DataContent; // property I made in MyListItem that gives access to the class it wraps
InputTextBlock block = item as InputTextBlock;
if (block != null)
{
block.StartEdit();
}
}
}
}
}
所有内容都被正确调用,但是在完成所有操作之后,上一个项目(我选中)将使键盘焦点恢复,并且不会导致堆栈中的任何项目处于编辑模式。 因此,例如,如果堆栈中的第一个项目处于编辑模式,一旦用户点击Tab键,堆栈中的第二个项目就会进入编辑模式,但第一个项目会立即获得键盘焦点。 任何人都能理解为什么会这样吗?
StackPanel默认情况下,Focusable为false。 建议确保它是真的。
另外,对于检查indeces,通常希望索引为<count。 所以你的索引+ 1可以==计算它是否= =计数 - 1.你不想要:
if (itemIndex < ...Count - 1)
那样,项目索引+ 1将始终<=计数 - 1?
if (itemIndex == ucSortableList.Children.Count - 1) { nextItem = stackPanelList.Children[itemIndex+1] as MyListItem; }
您也可以使用box.Focus()
而不是Keyboard.Focus(box)
但这可能没有必要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.