views:

112

answers:

1

Hi, 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...

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?
            }

        }
    }

Thank's in advance...

A: 

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();
}
Andrew Jackson
In Practice, every item I add to my Collection, the Binding make a new TextBox in ListView.Known item, how do I can put the blinking edit cursor on the related TextBox?
I've updated my answer above with a method which should allow you to do that.
Andrew Jackson