Silverlight:检索嵌套在Listbox中的控件

时间:2009-07-01 06:28:08

标签: silverlight listbox nested

我创建了一个列表框,可以生成动态控件,例如下拉菜单和日期选择器。我想检索行内的数据。通常,在Windows窗体中,我们通常索引... Items [i] .FindControl(“ControlID”)方法。你是如何在XAML中做的?

我需要在点击按钮时检索更改。

顺便说一句,这是我的xaml的简单视图:

<ListBox>
    <stackpanel>
           <TextBlock />
           <stackpanel>
                <grid>
                  <combobox />
                  <combobox/>
                  <datepicker />
                </grid>
          </stackpanel>
    </stackpanel>
</ListBox>

非常感谢你!

3 个答案:

答案 0 :(得分:2)

    private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        FrameworkElement selectedItem = (sender as ListBox).SelectedItem as FrameworkElement;
        List<FrameworkElement> children = new List<FrameworkElement>();
        children = GetChildren(selectedItem, ref children);
    }

    private List<FrameworkElement> GetChildren(FrameworkElement element, ref List<FrameworkElement> list)
    {
        int count = VisualTreeHelper.GetChildrenCount(element);

        for (int i = 0; i < count; i++)
        {
            FrameworkElement child = VisualTreeHelper.GetChild(element, i) as FrameworkElement;

            if(child != null)
            {
                list.Add(child);
                GetChildren(child, ref list);
            }
        }

        return list;
    }

这将返回所有FrameworkElements(包括路径,边框等)。只有在子类型为某种类型(ComboBox,StackPanel等)时,您才能轻松扩展它并递归调用GetChildren方法

答案 1 :(得分:2)

我有一个辅助类,它有以下两种方法来协助完成这类任务。

XAML:

    <ListBox Height="236" HorizontalAlignment="Left" Margin="31,23,0,0" 
             Name="listBox1" VerticalAlignment="Top" Width="245">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Horizontal" Name="sp">
                    <TextBlock Name="id">id</TextBlock>
                    <TextBox Name="test" Text="{Binding Key}"></TextBox>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

使用列表框,您可以传入所选项目:

var v1 =(ListBoxItem) listBox1.ItemContainerGenerator.ContainerFromIndex(
                         listBox1.SelectedIndex);


TextBox tb = GetChildByName<TextBox>(v1, "test");
tb.Text = "changed";      

您将获得所选列表框项的正确文本框。然后,您可以使用该引用更改其上的属性。

public T GetChildByName<T>(DependencyObject parent, string name) 
             where T : class
    {
        T obj = RecGetChildByName<T>(parent, name) as T;
        if (obj == null) throw new Exception("could find control "
                                + "of name as child");
        return obj;
    }

private DependencyObject RecGetChildByName<T>(DependencyObject parent, 
             string name)
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(parent); i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);

            Control childControl = child as Control;
            if (childControl != null)
            {
                if (childControl.Name == name) return child;
            }

            if (VisualTreeHelper.GetChildrenCount(child) > 0) 
                 return RecGetChildByName<T>(child, name);
        }

        return null;
    }

答案 2 :(得分:1)

最直接的方法是设置控件与对象的双向绑定,然后对象将告诉您设置的值是什么。

此外,您可以通过遍历对象的“内容”属性来浏览树,直到找到叶对象。

或者,您可以使用Selected项并调用VisualTreeHelper's GetChild方法,直到您处于叶对象。