WP ListBox 遍历DataTemplate(获取所有控件)

本文介绍如何在WPF ListBox中实现选中项时切换对应Image控件的图片,并将未选中项恢复为默认图片状态。通过自定义方法遍历ListBoxItem并找到指定名称的Image控件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目需求,ListBox选中切换其选中项的Image控件的图片,其它每项ListBoxItem的相应Image控件都设置为未选中图片.

解决方案适用于ComboBox等:

1.先看xaml文件:

<DataTemplate x:Name="BusTemplate" x:Key="LBDataTemplate">
            <StackPanel>
                <StackPanel Orientation="Horizontal" Margin="10">
                    <TextBlock Text="{Binding BusStr}" VerticalAlignment="Center"
                               FontSize="30" Foreground="White" Width="360"/>
                    <Image x:Name="BusStausImage" Source="/Image/d1.png"/>
                </StackPanel>
            </StackPanel>
        </DataTemplate>
 <ListBox ItemsSource="{Binding}" x:Name="BusList" SelectionChanged="ListBox_SelectionChanged" 
                     ItemTemplate="{StaticResource LBDataTemplate}">

2.现在要获取上面LisxBox的所有动态绑定项中的控件集合,然后全部换成默认图片。然后把当前选择项的Image换成选中样式的图片

<Image x:Name="BusStausImage" Source="/Image/1.png"/>

3.注册ListBox的SelectionChanged事件

  private void ListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            try
            {
                //通过函数FindFirstVisualChild遍历LisxBox获取Image集合
                List<Image> imgList = FindFirstVisualChild<Image>(BusList, "BusStausImage");
                foreach (Image img in imgList)
                {
                    img.Source = new BitmapImage(new Uri("/Image/车辆/d1.png", UriKind.Relative));
                }
                //获取当前选中项的Image,FindFirstVisualChild2获取单个
                ListBoxItem myListBoxItem = (ListBoxItem)BusList.ItemContainerGenerator.ContainerFromItem(BusList.SelectedItem);
                Image image = FindFirstVisualChild2<Image>(myListBoxItem, "BusStausImage");
                image.Source = new BitmapImage(new Uri("/Image/d2.png", UriKind.Relative));
            }
            catch (Exception)
            {   
            }
        }


自定义方法1:FindFirstVisualChild:
//遍历指定容器,根据控件名,返回适配的控件集合
public List<T> FindFirstVisualChild<T>(DependencyObject obj, string childName) where T : DependencyObject
        {
            List<T> childList = new List<T>();
//遍历指定容器
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is T && child.GetValue(NameProperty).ToString() == childName)
                {
                    childList.Add((T)child);
                }
//如果不存在,则继续遍历指定容器的子容器(则如果指定容器的子容器也就是第二层,遍历存在匹配的控件则跳出。不再遍历其第三层,继续遍历第二层)
                else
                {
                    List<T> t2 = FindFirstVisualChild<T>(child, childName);
                    if (t2 != null && t2.Count > 0)
                    {
                        foreach (T t in t2)
                        {
                            childList.Add(t);
                        }
                    }
                }
            }

            return childList;
        }

自定义方法2:FindFirstVisualChild2

//遍历容器,根据控件名,返回第一个适配的控件
 public T FindFirstVisualChild2<T>(DependencyObject obj, string childName) where T : DependencyObject
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(obj, i);
                if (child != null && child is T && child.GetValue(NameProperty).ToString() == childName)
                {
                    return (T)child;
                }
                else
                {
                    T childOfChild = FindFirstVisualChild2<T>(child, childName);
                    if (childOfChild != null)
                    {
                        return childOfChild;
                    }
                }
            }
            return null;
        }


自定义方法3:

//遍历指定容器的所有子控件(包括子控件的子控件),根据指定控件名称,返回控件集合。如果传“”则返回所有子空间的集合
public List<T> GetChildObjects<T>(DependencyObject obj, string name) where T : FrameworkElement
{
     DependencyObject child = null;
     List<T> childList = new List<T>();
     for (int i = 0; i <= VisualTreeHelper.GetChildrenCount(obj) - 1; i++)
         {
           child = VisualTreeHelper.GetChild(obj, i);
           if (child is T && (((T)child).Name == name || string.IsNullOrEmpty(name)))
              {
                 childList.Add((T)child);
              }
           childList.AddRange(GetChildObjects<T>(child, ""));//指定集合的元素添加到List队尾
         }
     return childList;
 }


参考自:

http://social.msdn.microsoft.com/Forums/vstudio/en-US/a01eb1d5-cfc1-47fc-a8e5-45f7f02e8119/wpf-finding-control-inside-itemtemplates-datatemplate?forum=wpf

http://blog.youkuaiyun.com/wushang923/article/details/6742378

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值