我有一个自定义类型VariableValueViewModel的集合(VariableValueCollection) 用ListView绑定的对象。 WPF关注:
<ListView ItemsSource="{Binding VariableValueCollection}" Name="itemList">
<ListView.Resources>
<DataTemplate DataType="{x:Type vm:VariableValueViewModel}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox TabIndex="{Binding Path=Index, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Grid.Column="0" Name="tbValue" Focusable="True" LostFocus="tbValue_LostFocus" GotFocus="tbValue_GotFocus" KeyDown="tbValue_KeyDown">
<TextBox.Text>
<Binding Path="Value" UpdateSourceTrigger="PropertyChanged" Mode="TwoWay">
<Binding.ValidationRules>
<ExceptionValidationRule></ExceptionValidationRule>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
</Grid>
</DataTemplate>
</ListView.Resources>
</ListView>
我的目标是在最后一行按“enter”时添加一个新行,然后将新行聚焦。为此,我检查该行是最后一行,并在这种情况下添加一行。但我不知道如何关注新的TextBox ......
这里是KeyPressed方法:
private void tbValue_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == System.Windows.Input.Key.Enter)
{
DependencyObject obj = itemList.ContainerFromElement((sender as TextBox));
int index = itemList.ItemContainerGenerator.IndexFromContainer(obj);
if( index == (VariableValueCollection.Count - 1) )
{
// Create a VariableValueViewModel object and add to collection. In binding, that create a new list item with a new TextBox
ViewModel.AddNewRow();
// How to set cursor and focus last row created?
}
}
}
答案 0 :(得分:0)
我可能误解了您的问题,但由于您将ListView绑定到VariableValueCollection,因此您对基础集合所做的任何更改都将反映在ListView中。
你应该只能从你的keydown事件处理程序中做这样的事情:
var newItem = new VariableValueViewModel();
VariableValueCollection.Add(newItem);
itemList.SelectedItem = newItem;
编辑:如何关注文本框:
以下方法允许您在可视化树中查找子控件:
/// <summary>
/// Finds the first child in the visual tree by type.
/// </summary>
public static T TryFindChild<T>(DependencyObject parent, Func<T, bool> predicate = null) where T : class {
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++) {
var child = VisualTreeHelper.GetChild(parent, i);
if ((child is T) && (predicate!=null && predicate(child as T))) {
return (T)((object)child);
} else {
T result = TryFindChild<T>(child, predicate);
if (result != null)
return result;
}
}
return null;
}
现在你可以这样做:
itemList.ItemContainerGenerator.ContainerFromItem(newItem);
TextBox textBox = TryFindChild<TextBox>(newItem) as TextBox;
if (textBox != null) {
textBox.Focus();
}