在列表框上使用VisualTreeHelper,无法获取listboxitems

时间:2011-06-22 12:06:28

标签: silverlight windows-phone-7

我有以下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(然后是文本框)?谢谢。

2 个答案:

答案 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);         
}