none
自定义控件中:如何获取ListBox列表下的Button RRS feed

  • 问题

  • <ListBox ItemsSource="{TemplateBinding ListboxItemsSource}" > <ListBox.Template> <ControlTemplate TargetType="ItemsControl"> <ScrollViewer> <StackPanel> <ItemsPresenter/> <Button Content="这是我要获取的按钮" /> </StackPanel> </ScrollViewer> </ControlTemplate> </ListBox.Template> <ListBox.ItemTemplate> <DataTemplate> <StackPanel> <TextBlock Text="{Binding Name}" FontSize="20" Foreground="Brown"/> <TextBlock Text="{Binding Age}" FontSize="30" Foreground="Crimson"/> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>

    以上是一个自定义控件中样式。

    如何通过ListBox的VirtualizingStackPanel来获取到列表下面的Button按钮?


    • 已编辑 Yvan Wang 2015年3月26日 1:47 删除注释
    2015年3月26日 1:38

答案

  • 明白你的意思,你想得到Button的点击事件.

    首先说一下为什么通过VisualTreeHelper查找不到Button,ListBox里面的数据模板有虚拟机制,意思就是当ListBox的数据源的项的数量有500个时,ListBox并不会把所以的项全都渲染出来,而VisualTreeHelper只能查找真实渲染到界面的元素

    解决方案有两种:

    1,绑定ICommand:这时候你需要在ListBox的ItemTemplate->DataTemplate中绑定一个点击事件。

    2,直接写事件:通过CodeBehind的方式给Button赋事件<Button Content="更多按钮" Click="SetMoreButton_Click"/>,当你点击Button时,后台cs文件中的SetMoreButton_Click事件可以直接触发。

    2015年4月1日 5:06

全部回复

  • 你好,

    我们可以使用VisualTreeHelper来遍历某个XAML元素,找到你想要的控件。你可以试试下面的代码。

    public static DependencyObject MyFindListBoxChildByName(DependencyObject parant, string ControlName) { int count = VisualTreeHelper.GetChildrenCount(parant); for (int i = 0; i < count; i++) {

    var MyChild = VisualTreeHelper.GetChild(parant, i); if (MyChild is FrameworkElement && ((FrameworkElement)MyChild).Name == ControlName) return MyChild; var FindResult = MyFindListBoxChildByName(MyChild, ControlName); if (FindResult != null) return FindResult; } return null; }

    在其他地方调用如下,"btn"为control template里面你要找的控件的名字

    var button =MyFindListBoxChildByName(listbox1,"btn") as Button;
    button.Content = "hello,world";
    



    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年3月26日 10:13
  • 请说的详细一些,最好把你想实现的功能列出来,谢谢。
    2015年3月26日 10:13
  • 将获取到的ListBox传入后。  

    int count = VisualTreeHelper.GetChildrenCount(listbox); 

    到的count为零啊。

    而我能通过下述获取到内容:

    GetChild<VirtualizingStackPanel>(listbox);//这里只是获取VirtualizingStackPanel控件

    方法为:

    public static IEnumerable<FrameworkElement> GetItemsInView(this DependencyObject itemsControl)
            {
                //获取列表里的VistualizingStackPanel类型的子对象  
                //里面存放的是实例化的可视元素
                VirtualizingStackPanel vsp = GetChild<VirtualizingStackPanel>(itemsControl);
                //循环可视化元素
                int firstVisibleItem = (int)vsp.VerticalOffset; //垂直偏移量
                int visibleItemCount = (int)vsp.ViewportHeight; //可视区内容大小
                for (int index = firstVisibleItem; index <= firstVisibleItem + visibleItemCount + 1; index++)
                {
                    var item = (itemsControl as ItemsControl).ContainerFromIndex(index) as FrameworkElement;
                    if (item == null)
                    {
                        continue;
                    }
                    yield return item;
                }
            }

    但我查看了vsp的所有子元素   这里只是列表中的元素。

    我想要找到的是列表下面多出来的那个按钮。(也就是点这个按钮,列表会增加)

    2015年3月27日 2:48
  • 好的。   我写一个CustomControl自定义控件   其中列表除了List.ItemTemlate绑定了数据之外 

    我让他以下面这种方式呈现:

    <ListBox.Template>
                                    <ControlTemplate TargetType="ItemsControl">
                                        <ScrollViewer>
                                            <StackPanel>
                                                <ItemsPresenter/>
                                                <Button Content="更多按钮" />
                                            </StackPanel>                       
                                        </ScrollViewer>
                                    </ControlTemplate>
                                </ListBox.Template>

    也就是在列表下面增加了一个“更多”按钮,点击这个按钮,可以添加列表数据。

    那现在我就要对“更多”按钮进行处理了,让数据增加了。所以我要先获取到这个按钮。

    只能够通过可视化树来获取。   目前ListBox控件我已经获取到。并且也能够获取到列表中的数据了。

    就是不知道如何获取到这个"更多"按钮。


    2015年3月27日 2:54
  • 你好,

    在我第一个post里面给出的代码在我这边其实是可以找到那个Button的,但看上去好像你那里无法运行。请建立一个可重现问题的工程,然后传到云盘上共享个链接到这里,看看到底是什么原因。


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place.
    Click HERE to participate the survey.

    2015年3月31日 2:18
  • 明白你的意思,你想得到Button的点击事件.

    首先说一下为什么通过VisualTreeHelper查找不到Button,ListBox里面的数据模板有虚拟机制,意思就是当ListBox的数据源的项的数量有500个时,ListBox并不会把所以的项全都渲染出来,而VisualTreeHelper只能查找真实渲染到界面的元素

    解决方案有两种:

    1,绑定ICommand:这时候你需要在ListBox的ItemTemplate->DataTemplate中绑定一个点击事件。

    2,直接写事件:通过CodeBehind的方式给Button赋事件<Button Content="更多按钮" Click="SetMoreButton_Click"/>,当你点击Button时,后台cs文件中的SetMoreButton_Click事件可以直接触发。

    2015年4月1日 5:06