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