views:

125

answers:

1

Hi everyone,

I have a WPF ItemsControl that is bound to an ObservableCollection.

The XAML:

    <ItemsControl Name="mItemsControl">
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <TextBox Text="{Binding Mode=OneWay}"></TextBox>    
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>

The codebehind:

    private ObservableCollection<string> mCollection = new ObservableCollection<string>();

    public MainWindow()
    {
        InitializeComponent();

        this.mCollection.Add("Test1");
        this.mCollection.Add("Test2");
        this.mItemsControl.ItemsSource = this.mCollection;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.mCollection.Add("new item!");
    }

When I click a button, it adds a new string to the databound ObservableCollection which triggers a new TextBox to appear. I want to give this new textbox focus.

I've tried this technique from a related StackOverflow question but it always sets focus to the textbox before the newly created one.

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        this.mCollection.Add("new item!");

        // MoveFocus takes a TraversalRequest as its argument.
        TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Previous);

        // Gets the element with keyboard focus.
        UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;

        // Change keyboard focus.
        if (elementWithFocus != null)
        {
            elementWithFocus.MoveFocus(request);
        }
    }

My need seems simple enough, but it's almost like the new textbox doesn't really exist until a slight delay after something is added to the ObservableCollection.

Any ideas of what would work?

Thanks!

-Mike

A: 

Bit of a hack but try using the Dispatcher and BeginInvoke:

this.Dispatcher.BeginInvoke(new Action( ()=>{
    // MoveFocus takes a TraversalRequest as its argument.
    TraversalRequest request = new TraversalRequest(FocusNavigationDirection.Previous);

    // Gets the element with keyboard focus.
    UIElement elementWithFocus = Keyboard.FocusedElement as UIElement;

    // Change keyboard focus.
    if (elementWithFocus != null)
    {
        elementWithFocus.MoveFocus(request);
    }


}), DispatcherPriority.ApplicationIdle);
BFree