使用分层模板Treeview进行绑定

时间:2013-09-03 06:09:36

标签: wpf treeview

嗨我有一个hiearchical模板的问题。 我编写了自定义树视图项并使用层次模板绑定。但是我的树视图没有更新。我提到了网站http://social.msdn.microsoft.com/Forums/vstudio/en-US/feac927d-b73c-4361-82f4-cd0a3f055ad0/treeview-binding-and-hierarchicaldatatemplate

我的xaml

    <Window.DataContext>
        <vm:ViewModel></vm:ViewModel>
    </Window.DataContext>
    <Grid>
        <TreeView  Name="FT" HorizontalAlignment="Stretch"  VerticalAlignment="Stretch" Grid.Row="1" Grid.ColumnSpan="4" ItemsSource="{Binding RootNode}"  >
            <TreeView.Resources>
                <DataTemplate DataType="{x:Type vm:FrthChild}">
                    <TextBlock Text="{Binding DisplayName}"/>
                </DataTemplate>

                <HierarchicalDataTemplate DataType="{x:Type vm:ThrdChild}"
         ItemsSource="{Binding FrthChilds}">
                    <TextBlock Text="{Binding DisplayName}"/>
                </HierarchicalDataTemplate>

                <HierarchicalDataTemplate
         DataType="{x:Type vm:SecndChild}"
        ItemsSource="{Binding ThrdChilds}">
                    <TextBlock Text="{Binding DisplayName}"/>
                </HierarchicalDataTemplate>

                <HierarchicalDataTemplate
         DataType="{x:Type vm:FstChild}"
         ItemsSource="{Binding SecndChilds}">
                    <TextBlock Text="{Binding DisplayName}"/>
                </HierarchicalDataTemplate>

                <HierarchicalDataTemplate  DataType="{x:Type vm:ROOT}" ItemsSource="{Binding FstChilds}">
                    <TextBlock Text="{Binding DisplayName}"/>
                </HierarchicalDataTemplate>
            </TreeView.Resources>
        </TreeView>
    </Grid>
</Window>

我的视图模型类

    namespace WpfApplication1 : INotifyPropertyChanged
    {
        public class ViewModel
        {
            public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }
            public ViewModel()
            {
                RootNode = new ROOT();
            }
            public ROOT RootNode
            {
                get;
                set;
            }
        }
    }

我的树状视图项目类

namespace WpfApplication1
{
    public class NodeTypes
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(PropertyChangedEventArgs e)
        {
            if (PropertyChanged != null)
                PropertyChanged(this, e);
        }
        public string DisplayName
        { get; set; }
    }
    public class ROOT : NodeTypes
    {
        public ROOT()
        {
            FstChilds = new ObservableCollection<FstChild>();
        }
        public ObservableCollection<FstChild> FstChilds { get; set; }
    }
    public class FstChild : NodeTypes
    {
        public FstChild()
        {
            SecndChilds = new ObservableCollection<SecndChild>();
        }
        public ObservableCollection<SecndChild> SecndChilds { get; set; }
    }
    public class SecndChild : NodeTypes
    {
        public SecndChild()
        {
            ThrdChilds = new ObservableCollection<ThrdChild>();
        }
        public ObservableCollection<ThrdChild> ThrdChilds { get; set; }
    }
    public class ThrdChild : NodeTypes
    {
        public ThrdChild()
        {
            FrthChilds = new ObservableCollection<FrthChild>();
        }
        public ObservableCollection<FrthChild> FrthChilds { get; set; }
    }
    public class FrthChild : NodeTypes
    {

    }
}

我在我的xaml.cs中添加了一些项目...我这样做是为了便于编写测试应用程序..我将在稍后使用ICommand实现它。

Xaml.cs

        namespace WpfApplication1
        {
            /// <summary>
            /// Interaction logic for MainWindow.xaml
            /// </summary>
            public partial class MainWindow : Window
            {
                public MainWindow()
                {
                    InitializeComponent();
                    ((ViewModel)this.DataContext).RootNode = new ROOT();
                    ((ViewModel)this.DataContext).RootNode.DisplayName = "sdsds";
                    ((ViewModel)this.DataContext).OnPropertyChanged(new PropertyChangedEventArgs("RootNode"));
                    ((ViewModel)this.DataContext).RootNode.OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
                    ((ViewModel)this.DataContext).RootNode.FstChilds.Add(new FstChild());
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].DisplayName = "sered";
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds.Add(new SecndChild());
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].DisplayName = "dsdsd";
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].ThrdChilds.Add(new ThrdChild());
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].ThrdChilds[0].DisplayName = "dsds";
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].ThrdChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].ThrdChilds[0].FrthChilds.Add(new FrthChild());
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].ThrdChilds[0].FrthChilds[0].DisplayName = "dsds";
                    ((ViewModel)this.DataContext).RootNode.FstChilds[0].SecndChilds[0].ThrdChilds[0].FrthChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));

                }
            }
        }

任何人都可以帮助我吗?

2 个答案:

答案 0 :(得分:1)

您尚未针对属性引发propertychanged事件。你应该这样做:

           private ROOT rootNode;
            public ROOT RootNode
            {
                get
                  {
                    return _rootNode;
                  }
                set
                   {
                      _rootNode = value;
                       OnPropertyChanged(new PropertyChangedEventArgs("RootNode"));
                     }
            }

类似地,对于所有类,从属性的setter中调用PropertyChanged事件。

由于

答案 1 :(得分:1)

RootNode必须是IEnumerable,所以我改变了你的ViewModel:

    public class ViewModel
{
    public event PropertyChangedEventHandler PropertyChanged;
    public void OnPropertyChanged(PropertyChangedEventArgs e)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, e);
    }
    public ViewModel()
    {
        RootNode = new ObservableCollection<ROOT>() { new ROOT() };
    }
    public ObservableCollection<ROOT> RootNode
    {
        get;
        set;
    }
}

和MainWindow ctor:

        public MainWindow()
    {
        InitializeComponent();
        // ((ViewModel)this.DataContext).RootNode = new ROOT();
        ((ViewModel)this.DataContext).RootNode[0].DisplayName = "sdsds";
        ((ViewModel)this.DataContext).OnPropertyChanged(new PropertyChangedEventArgs("RootNode"));
        ((ViewModel)this.DataContext).RootNode[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
        ((ViewModel)this.DataContext).RootNode[0].FstChilds.Add(new FstChild());
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].DisplayName = "sered";
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds.Add(new SecndChild());
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].DisplayName = "dsdsd";
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].ThrdChilds.Add(new ThrdChild());
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].ThrdChilds[0].DisplayName = "dsds";
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].ThrdChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].ThrdChilds[0].FrthChilds.Add(new FrthChild());
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].ThrdChilds[0].FrthChilds[0].DisplayName = "dsds";
        ((ViewModel)this.DataContext).RootNode[0].FstChilds[0].SecndChilds[0].ThrdChilds[0].FrthChilds[0].OnPropertyChanged(new PropertyChangedEventArgs("DisplayName"));

    }

全部显示。

修改 关于您的上一条评论,您可以尝试使用ItemContainer样式

        <TreeView.ItemContainerStyle>
            <Style TargetType="TreeViewItem">
                <Setter Property="IsSelected" Value="{Binding YourProperty}"></Setter>
            </Style>
        </TreeView.ItemContainerStyle>