C# 从ListBox can';不要让孩子们有';没有人看过

C# 从ListBox can';不要让孩子们有';没有人看过,c#,wpf,xaml,C#,Wpf,Xaml,我在WPF中有一个列表框,如下面的XAML。它充满了包含复选框和标签的ListBoxItems。我在顶部的一个项目是“全选”选项。当我单击全选选项时,我有一个处理程序可以遍历所有列表框项目,它应该选中所有其他列表框子项上的所有复选框。问题是它只处理可见的子对象,当它点击不可见的listboxitems时,VisualTreeHelper在查找特定类型的对象(如复选框)时似乎返回null。VisualTreeHelper在这里似乎有问题。我用错了吗?谢谢你的帮助。另一个细节——如果我滚动并查看所有

我在WPF中有一个列表框,如下面的XAML。它充满了包含复选框和标签的ListBoxItems。我在顶部的一个项目是“全选”选项。当我单击全选选项时,我有一个处理程序可以遍历所有列表框项目,它应该选中所有其他列表框子项上的所有复选框。问题是它只处理可见的子对象,当它点击不可见的listboxitems时,VisualTreeHelper在查找特定类型的对象(如复选框)时似乎返回null。VisualTreeHelper在这里似乎有问题。我用错了吗?谢谢你的帮助。另一个细节——如果我滚动并查看所有listboxitems至少一次,它就可以正常工作

乔丹

XAML-一个包含大量子项的简单列表框(为简洁起见,仅显示第一个子项)


所有字符
C#-两个函数,第一个是帮助器方法,它使用VisualTreeHelper(我在某个网站上发现)遍历对象树。第二个函数是“全选”listboxitem的单击处理程序。它遍历所有子项并尝试选中所有复选框

    private T FindControlByType<T>(DependencyObject container, string name) where T : DependencyObject
    {
        T foundControl = null;

        //for each child object in the container
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(container); i++)
        {
            //is the object of the type we are looking for?
            if (VisualTreeHelper.GetChild(container, i) is T && (VisualTreeHelper.GetChild(container, i).GetValue(FrameworkElement.NameProperty).Equals(name) || name == null))
            {
                foundControl = (T)VisualTreeHelper.GetChild(container, i);
                break;
            }
            //if not, does it have children?
            else if (VisualTreeHelper.GetChildrenCount(VisualTreeHelper.GetChild(container, i)) > 0)
            {
                //recursively look at its children
                foundControl = FindControlByType<T>(VisualTreeHelper.GetChild(container, i), name);
                if (foundControl != null)
                    break;
            }
        }

        return foundControl;
    }

    private void AllCharactersClicked(object sender, RoutedEventArgs e)
    {

        MainWindow.Instance.BadChars.Clear();

        int count = 0;
        foreach (ListBoxItem item in CharacterListBox.Items)
        {
            CheckBox cb = FindControlByType<CheckBox>(item, null);                
            Label l = FindControlByType<Label>(item, null);
            if (cb != null && l != null)
            {
                count++;
                cb.IsChecked = true;

                if (cb.IsChecked == true)
                {
                    string sc = (string)l.Content;
                    if (sc.Length == 1)
                    {
                        char c = Char.Parse(sc);
                        MainWindow.Instance.BadChars.Add(c);
                    }
                }
            }

        }

    }
private T FindControlByType(DependencyObject容器,字符串名称),其中T:DependencyObject
{
T foundControl=null;
//对于容器中的每个子对象
for(int i=0;i0,则为else
{
//递归地看它的子对象
foundControl=FindControlByType(VisualTreeHelper.GetChild(容器,i),名称);
if(foundControl!=null)
打破
}
}
返回控制;
}
private void AllCharactersClicked(对象发送方,路由目标)
{
MainWindow.Instance.BadChars.Clear();
整数计数=0;
foreach(CharacterListBox.Items中的ListBoxItem项)
{
复选框cb=FindControlByType(项,空);
标签l=FindControlByType(项,空);
如果(cb!=null&&l!=null)
{
计数++;
cb.IsChecked=true;
如果(cb.IsChecked==true)
{
字符串sc=(字符串)l.Content;
如果(sc.Length==1)
{
char c=char.Parse(sc);
main window.Instance.BadChars.Add(c);
}
}
}
}
}

那些随处可见的视觉树木行走方法是一种瘟疫。你几乎不需要这些


只需将绑定到包含
复选框属性的对象列表
,创建一个()并将该属性绑定到
复选框
。在代码中,只需迭代绑定到
ItemsSource
的集合,并设置属性。

那些随处可见的可视化树漫游方法是一种瘟疫。你几乎不需要这些


只需将绑定到包含
复选框属性的对象列表
,创建一个()并将该属性绑定到
复选框
。在代码中,只需迭代绑定到ItEsStase的集合,并设置PARPYTY。

您应该考虑使用绑定而不是浏览可视化树。listbox使用虚拟化stackpanel(sp),它仅在需要时分配可视控件(出于效率原因)。这意味着一个控件可能被分配,也可能不被分配,使得遍历可视化树来执行数据操作变得杂乱无章(这也不是可视化树的目的)。正如其他人提到的那样,绑定是一种可行的方式。你应该考虑使用绑定而不是浏览视觉树。listbox使用虚拟化stackpanel(sp),它仅在需要时分配可视控件(出于效率原因)。这意味着一个控件可能被分配,也可能不被分配,使得遍历可视化树来执行数据操作变得杂乱无章(这也不是可视化树的目的)。正如其他人提到的那样,绑定是一条必由之路。
    private T FindControlByType<T>(DependencyObject container, string name) where T : DependencyObject
    {
        T foundControl = null;

        //for each child object in the container
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(container); i++)
        {
            //is the object of the type we are looking for?
            if (VisualTreeHelper.GetChild(container, i) is T && (VisualTreeHelper.GetChild(container, i).GetValue(FrameworkElement.NameProperty).Equals(name) || name == null))
            {
                foundControl = (T)VisualTreeHelper.GetChild(container, i);
                break;
            }
            //if not, does it have children?
            else if (VisualTreeHelper.GetChildrenCount(VisualTreeHelper.GetChild(container, i)) > 0)
            {
                //recursively look at its children
                foundControl = FindControlByType<T>(VisualTreeHelper.GetChild(container, i), name);
                if (foundControl != null)
                    break;
            }
        }

        return foundControl;
    }

    private void AllCharactersClicked(object sender, RoutedEventArgs e)
    {

        MainWindow.Instance.BadChars.Clear();

        int count = 0;
        foreach (ListBoxItem item in CharacterListBox.Items)
        {
            CheckBox cb = FindControlByType<CheckBox>(item, null);                
            Label l = FindControlByType<Label>(item, null);
            if (cb != null && l != null)
            {
                count++;
                cb.IsChecked = true;

                if (cb.IsChecked == true)
                {
                    string sc = (string)l.Content;
                    if (sc.Length == 1)
                    {
                        char c = Char.Parse(sc);
                        MainWindow.Instance.BadChars.Add(c);
                    }
                }
            }

        }

    }