ItemsControl and Focus Issue

I have an ItemsControl which is giving me issues. It has a DataTemplate, which contains a TextBox that is bound to a property in the code-behind. When I press the Enter key, a new element is inserted into the property. After this happens, the focus of the item in the datatemplate should shift down one item in the ItemsControl (done programatically). However, it doesn't. Instead, it shifts by two elements. I put a recursive visual tree reader method in the control to try to figure out what's going on, and it looks like one of the visual elements is missing. However, I'm not sure what's causing this or how to fix it. Any help would be very much appreciated. Thanks!

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Collections.ObjectModel;
using System.IO;

namespace FunWithListBox.View
{
    /// <summary>
    /// Interaction logic for EntryListView.xaml
    /// </summary>
    public partial class EntryListView : UserControl
    {
        private ObservableCollection<string> itemList;
        public ObservableCollection<string> ItemList
        {
            get { return itemList; }
            set { itemList = value; }
        }

        public EntryListView()
        {
            InitializeComponent();

            itemList = new ObservableCollection<string>();
            itemList.Add("First string in the list.");
            itemList.Add("Second string in the list.");
            itemList.Add("Third string in the list.");
            itemList.Add("Fourth string in the list.");
            itemList.Add("Fifth string in the list.");

            DataContext = this;
        }

        private void UserControl_KeyDown(object sender, KeyEventArgs e)
        {
            Type focType = Keyboard.FocusedElement.GetType();

            if (focType == typeof(TextBox))
            {
                if (e.Key == Key.Return)
                {
                    TextBox tbxWithFocus = Keyboard.FocusedElement as TextBox;

                    int index = itemList.IndexOf(tbxWithFocus.DataContext as string);

                    string strToCursor = tbxWithFocus.Text.Substring(0, tbxWithFocus.CaretIndex);
                    string strPastCursor = tbxWithFocus.Text.Substring(tbxWithFocus.CaretIndex);

                    itemList[index] = strToCursor;

                    if (index == itemList.Count - 1)
                        itemList.Add(strPastCursor);
                    else
                        itemList.Insert(index + 1, strPastCursor);

                    TextWriter tw = new StreamWriter("sampleVisualTree.txt");
                    tw.Write(getVisualTree(myItemsControl, 2));
                    tw.Close();

                    tbxWithFocus.MoveFocus(new TraversalRequest(FocusNavigationDirection.Down));
                }
            }
        }

        private string getVisualTree(DependencyObject dpo, int depth)
        {
            string treeString;

            treeString = String.Empty.PadRight(depth, ' ') + dpo.ToString();

            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(dpo); i++)
                treeString +=
                    Environment.NewLine +
                    getVisualTree(VisualTreeHelper.GetChild(dpo, i), depth + 2);

            return treeString;
        }
    }
}

Also, here's the xaml:

<UserControl x:Class="FunWithListBox.View.EntryListView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Height="300" Width="300"
             KeyDown="UserControl_KeyDown">
    <Grid>
        <ItemsControl ItemsSource="{Binding Path=ItemList}"
                      x:Name="myItemsControl">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <TextBox Text="{Binding Mode=TwoWay,
                                            UpdateSourceTrigger=PropertyChanged,
                                            Path=.}"
                             BorderThickness="0" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </Grid>
</UserControl>

Cheers,

Andrew

Answers


I found the problem. Apparently, I needed to make a call to this.UpdateLayout() in order to have the visual tree redrawn before changing the focused element.


Need Your Help

Can sample weight be used in Spark MLlib Random Forest training?

scala apache-spark random-forest apache-spark-mllib

I am using Spark 1.5.0 MLlib Random Forest algorithm (Scala code) to do two-class classification. As the dataset I am using is highly imbalanced, so the majority class is down sampled at 10% sampling

Get GPS location from MLMediaObject on OS X

objective-c macos gps photos media-library

I'm getting started with the Media Library Framework on OS X, specifically with regard to accessing a user's Photos library. After a lot of wrangling I was able to get access to each photo as a