none
为什么调用 TreeView.ItemContainerGenerator.ContainerFromItem(...)总是返回 null ? RRS feed

  • 问题

  • 为什么调用 TreeView.ItemContainerGenerator.ContainerFromItem(...)总是返回 null ?

    我定义了一个类ArchiveGroup_Node, 然后生成了一个集合ObservableCollection<ArchiveGroup_Node> mydata并填充的数据,然后绑定到TreeView.ItemsSource=mydata,显示结果很正常,但是当我调用TreeView.ItemContainerGenerator.ContainerFromItem(mydata[0].Children[0])  时总是返回空值“null”,但是调用TreeView.ItemContainerGenerator.ContainerFromItem(mydata[0]) 却可以正常的返回TreeViewItem类型的容器,也就是说只有数据集的根节点可以正常的返回与之对应的容器,而子节点却无法利用TreeView.ItemContainerGenerator.ContainerFromItem返回与之相关的容器,不知道是哪里做错了?


     public class ArchiveGroup_Node : INotifyPropertyChanged
        {
            public ArchiveGroup_Node()
            {
                Children=new ObservableCollection<ArchiveGroup_Node> ();
            }
            private ArchiveGroup_Node _meparent = null;
            public ObservableCollection<ArchiveGroup_Node> Children
            {get; set;}
            public ArchiveGroup_Node Parent
            {
                get { return _meparent; }
                set { _meparent = value; }
            }
            private int _id;
            private int _a_parentid;
            private string _a_name;
            private string _a_detail;
            private bool _a_isdel;
            private int _r_w;
            private string _a_value;
            //----------------------------------------------------------------------
            public int id { get { return _id; } set { _id = value; NotifyPropertyChanged("id"); } }
            public int a_parentid { get { return _a_parentid; } set { _a_parentid = value; NotifyPropertyChanged("a_parentid"); } }
            public string a_name { get { return _a_name; } set { _a_name = value; NotifyPropertyChanged("a_name"); } }
            public string a_value { get { return _a_value; } set { _a_value = value; NotifyPropertyChanged("a_value"); } }
            public string a_detail { get { return _a_detail; } set { _a_detail = value; NotifyPropertyChanged("a_detail"); } }
            public bool a_isdel { get { return _a_isdel; } set { _a_isdel = value; NotifyPropertyChanged("a_isdel"); } }
            public int r_w { get { return _r_w; } set { _r_w = value; NotifyPropertyChanged("r_w"); } }
            //-------------------------------------------
            public event PropertyChangedEventHandler PropertyChanged;
            public void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }
    }
    XAML部分
            <controls:TreeView x:Name="ArchiveGroup" Grid.Column="0" SelectedItemChanged="ArchiveGroup_SelectedItemChanged"  >
                <controls:TreeView.ItemTemplate>
                    <common:HierarchicalDataTemplate  ItemsSource="{Binding Children}">
                        <StackPanel Orientation="Horizontal" Tag="{Binding a_detail}">
                            <TextBlock Text="{Binding a_name}" />
                        </StackPanel>
                    </common:HierarchicalDataTemplate>
                </controls:TreeView.ItemTemplate>
            </controls:TreeView>

    2009年9月27日 4:00

答案

全部回复

  • 你好,
    请参考:
    http://forums.silverlight.net/forums/t/65277.aspx
    Please remember to mark the replies as answers if they help and unmark them if they provide no help. Welcome to the All-In-One Code Framework http://cfx.codeplex.com/! If you have any feedback, please tell us.
    2009年9月29日 6:33
    版主
  • 首先感谢Allen Chen的回答,但是问题还是没有完全解决,我不太清楚SilverLight开发成员是如何对展现数据的容器进行处理的,但是我测试的时候发现没有被展开的TreeViewItem节点好像没有被创建实例,也就是说即使进行了数据绑定,也无法通过数据与控件容器关联,所以总是返回“null“,在Allen Chen提示的http://forums.silverlight.net/forums/t/65277.aspx中,JustinAngel的回答也只是针对于已经展开的TreeViewItem节点进行遍历搜索,但是我们总不能让用户在使用这个功能前先展开所有TreeViewItem节点,另外 TreeView.ExpandAll() 并不一定会展开所有与TreeView绑定而创建的TreeViewItem节点,我想这些是不是SilverLight开发成员为了减少程序运行时内存消耗而采用的一种策略,也可能是我的理解有错误。希望能得到大家的更多提示,谢谢。

    2009年10月9日 1:01
  • 我采用的搜索并展开TreeView任意节点的方法:首先在TreeView的数据源上搜索目标数据,然后返回一个结果集,结果集里按顺序存放了从根节点到目标节点的数据,然后调用TreeView.ExpandPath(结果集)。

    2009年10月9日 2:32