我有以下XAML:
<ListBox HorizontalAlignment="Left" Margin="0,6,0,10" Name="listBox1" Width="468" ItemsSource="{Binding}" Grid.ColumnSpan="1">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBox Name="txt1" Text="{Binding Propty1}" IsEnabled="False"></TextBox>
<CheckBox IsChecked="{Binding Propty2}" Name="{Binding Propty2}" Click="chk_Clicked"></CheckBox>
<TextBox Text="{Binding Propty2}" Name="{Binding Propty3}" GotFocus="txt_GotFocus" LostFocus="txt_OnLostFocus" KeyDown="txt_OnKeyDown"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>
事件发生后(单击列表框外的按钮,然后重新加载列表框中的数据),我需要关注列表框中的一个文本框。我使用VisualTreeHelper浏览列表框。这是代码:
void SetFocusOnTextBox(DependencyObject element)
{
ListBoxItem listItem = element as ListBoxItem;
if (listItem != null)
{
//find textbox and set focus here
}
int children = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < children; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(element, i);
SetFocusOnTextBox(child);
}
}
但是,当我在下面的代码行中调用该方法时,我没有得到任何类型列表框的项目:
SetFocusOnTextBox(listBox1);
我获得ListBox,ScrollViewer,Border,Grid,ContentPresenter,ItemsPresenter,VirtualizingStackPanel等,但没有listboxitems。我究竟做错了什么?如何在列表框中找到listboxitems(然后是文本框)?谢谢。
答案 0 :(得分:2)
Silverlight是异步的!
...重新加载列表框中的数据......
使用某些新数据更改DataContext时,并不意味着将立即加载实际数据。就在您尝试获取ListboxItem之前,只需简单地调用listBox1.UpdateLayout
,一切都应该没问题。
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
ReloadData();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
// 1 - Uncomment this line to crush your app
// ReloadData();
// 2 - Uncomment this line to fix everything
// listBox1.UpdateLayout();
// UpdateLayout - ensures that actual data is loaded to UI,
// all items are created and rendered
GetItemsRecursive(listBox1);
}
private void GetItemsRecursive(DependencyObject lb)
{
var childrenCount = VisualTreeHelper.GetChildrenCount(lb);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(lb, i);
if (child is ListBoxItem)
{
MessageBox.Show(child.GetType().ToString());
return;
}
GetItemsRecursive(child);
}
}
private void ReloadData()
{
listBox1.DataContext = new List<Classs>() {
new Classs{ Propty1 = "sasda", Propty2 = false, Propty3 = "asdasda"},
new Classs{ Propty1 = "sasda", Propty2 = true, Propty3 = "asdasda"},
new Classs{ Propty1 = "sasda", Propty2 = false, Propty3 = "asdasda"}
};
}
}
public class Classs
{
public string Propty1 { get; set; }
public bool Propty2 { get; set; }
public string Propty3 { get; set; }
}
答案 1 :(得分:0)
请尝试使用下面的代码片段获取ListBox项目中的TextBox。
ListBox listbox = element as ListBox;
if (listbox != null && listbox.SelectedItem !=null)
{
//find textbox and set focus here
Textbox thisTextBox = (listbox.SelectedItem).Find("txt1") as Textbox;
if(thisTextBox !=null)
{
thisTextBox.Focus();
return;
}
}
int children = VisualTreeHelper.GetChildrenCount(element);
for (int i = 0; i < children; i++)
{
DependencyObject child = VisualTreeHelper.GetChild(element, i);
SetFocusOnTextBox(child);
}