Retrieve a TextBox element dynamically created and Focus it
I have a collection (VariableValueCollection) of custom type VariableValueViewModel objects binded with a ListView. WPF Follow:
<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>
My Goal is to add a new row when I press "enter" on last row, and Focus the new row. To do that, I check that row is the last row and add a new row in that case. But I don't know how to focus the new TextBox...
开发者_C百科Here the KeyPressed method:
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?
}
}
}
I might be misunderstanding your problem but since you are binding your ListView to the VariableValueCollection, any changes you make to the underlying collection will be reflected in your ListView.
You should just be able do something like this from your keydown event handler:
var newItem = new VariableValueViewModel();
VariableValueCollection.Add(newItem);
itemList.SelectedItem = newItem;
EDIT: How to focus the textbox:
The method below allows you to find a child control in a visual tree:
/// <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;
}
Now you can do something like this:
itemList.ItemContainerGenerator.ContainerFromItem(newItem);
TextBox textBox = TryFindChild<TextBox>(newItem) as TextBox;
if (textBox != null) {
textBox.Focus();
}
精彩评论