Получить элемент TextBox, созданный динамически, и сфокусировать его - PullRequest
0 голосов
/ 07 мая 2010

У меня есть коллекция (VariableValueCollection) пользовательского типа VariableValueViewModel объекты, связанные с 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>

Моя цель - добавить новую строку, когда я нажимаю «ввод» в последней строке, и сфокусировать новую строку. Для этого я проверяю, что строка является последней строкой, и добавляю новую строку в этом случае. Но я не знаю, как сфокусировать новый 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?
            }

        }
    }

1 Ответ

0 голосов
/ 12 мая 2010

Возможно, я неправильно понимаю вашу проблему, но поскольку вы привязываете свой ListView к VariableValueCollection, любые изменения, которые вы вносите в базовую коллекцию, будут отражены в вашем ListView.

Вы должны просто иметь возможность сделать что-то подобноеиз вашего обработчика события нажатия клавиш:

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();
}
...