我创建了一个用户控件,我称之为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键,堆栈中的第二个项目就会进入编辑模式,但第一个项目会立即获得键盘焦点。谁能理解为什么会这样?
答案 0 :(得分:0)
StackPanel默认情况下,Focusable为false。建议确保它是真的。
另外,对于检查indeces,通常希望索引为&lt;计数。所以你的索引+ 1可以==计算它是否= =计数 - 1.你不想要:
if (itemIndex < ...Count - 1)
这样,项目索引+ 1将始终为&lt; = Count - 1?
if (itemIndex == ucSortableList.Children.Count - 1)
{
nextItem = stackPanelList.Children[itemIndex+1] as MyListItem;
}
此外,您可以使用box.Focus()
代替Keyboard.Focus(box)
,但这可能不是必需的。