绑定树视图部分刷新

时间:2012-08-30 12:50:08

标签: c# wpf data-binding treeview

我做了一个镜头应用来举例说明我的问题:

继承了window1.xaml

    <Window
        x:Class="TreeViewStepByStep.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:sys="clr-namespace:System;assembly=mscorlib"
        mc:Ignorable="d"
        Width="400"
        Height="600">
        <Window.Resources />
        <Grid>
            <TreeView
                Margin="0,21,0,0"
                ItemsSource="{Binding Regions}"
                HorizontalAlignment="Left"
                Width="221">

                <TreeView.ItemTemplate>
                    <HierarchicalDataTemplate
                        ItemsSource="{Binding Type}">
                        <TextBlock
                            Text="{Binding Name}" />

                        <HierarchicalDataTemplate.ItemTemplate>
                            <HierarchicalDataTemplate
                                ItemsSource="{Binding Locations}">
                                <TextBlock
                                    Text="{Binding Name}" />

                                <HierarchicalDataTemplate.ItemTemplate>
                                    <DataTemplate>
                                        <TextBlock
                                            Text="{Binding}" />
                                    </DataTemplate>
                                </HierarchicalDataTemplate.ItemTemplate>

                            </HierarchicalDataTemplate>
                        </HierarchicalDataTemplate.ItemTemplate>

                    </HierarchicalDataTemplate>
                </TreeView.ItemTemplate>

            </TreeView>



            <Button
                Content="Populate"
                Height="23"
                HorizontalAlignment="Left"
                Margin="227,21,0,0"
                Name="button2"
                VerticalAlignment="Top"
                Width="96"
                Click="button2_Click" />
            <Button
                Content="Add child"
                Height="23"
                HorizontalAlignment="Left"
                Margin="227,49,0,0"
                Name="button3"
                VerticalAlignment="Top"
                Width="96"
                Click="button3_Click" />
            <Button
                Content="Modify"
                Height="23"
                HorizontalAlignment="Left"
                Margin="227,106,0,0"
                Name="button4"
                VerticalAlignment="Top"
                Width="96"
                Click="button4_Click" />
            <Button
                Content="Add root level"
                Height="23"
                HorizontalAlignment="Left"
                Margin="227,135,0,0"
                Name="button5"
                VerticalAlignment="Top"
                Width="96"
                Click="button5_Click" />
        </Grid>
    </Window>

这是window1.xaml.cs

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    using System.Collections.ObjectModel;

    namespace TreeViewStepByStep
    {
        /// <summary>
        /// Interaction logic for Window1.xaml
        /// </summary>
        public partial class Window1 : Window
        {
            Collection<Region> regions;

            public Window1()
            {
                InitializeComponent();
            }

            private void button2_Click(object sender, RoutedEventArgs e)
            {
                Region sms = new Region("São Mateus do Sul")
                {
                    Type =
                    {
                        new Types("Placemarks")
                        {
                            Locations = 
                            { 
                                "Pine trees", 
                                "Barn", 
                                "Phantom city" 
                            }
                        },

                        new Types("Planning")
                        { 
                            Locations = 
                            { 
                                "Geada", 
                                "Por do sol" 
                            }
                        },
                    }
                };

                Region others = new Region("Outros")
                {
                    Type =
                    {
                        new Types("Placemarks")
                        {
                            Locations = 
                            { 
                                "Road", 
                                "Waterfall" 
                            }
                        },
                        new Types("Planning")
                        { 
                            Locations = 
                            { 
                                "Moon" 
                            }
                        },  
                    }
                };

                regions = new Collection<Region>() { sms, others };

                DataContext = new
                {
                    Regions = regions
                };
            }

            private void button3_Click(object sender, RoutedEventArgs e)
            {
                this.regions[1].Type.Add(new Types("New folder")
                                             { 
                                                Locations = 
                                                { 
                                                    "Test" 
                                                }
                                             }
                                        );
            }

            private void button4_Click(object sender, RoutedEventArgs e)
            {
                this.regions[0].Name = "Edited";
            }

            private void button5_Click(object sender, RoutedEventArgs e)
            {
                this.regions.Add(new Region("My new region"));
            }
        }

        public class Region
        {
            public Region(string name)
            {
                Name = name;
                Type = new ObservableCollection<Types>();
            }

            public string Name { get; set; }
            public ObservableCollection<Types> Type { get; set; }
        }

        public class Types
        {
            public Types(string name)
            {
                Name = name;
                Locations = new ObservableCollection<string>();
            }

            public string Name { get; private set; }
            public ObservableCollection<string> Locations { get; set; }
        }


    }

我的TreeView绑定到层次模型(区域变量)。当我单击“填充”时,它会将TreeView绑定到此变量。当我单击“添加子项”时,它会将一个子元素添加到绑定变量中,并反映在TreeView上。到目前为止一切都很好。

当我尝试修改现有元素的名称或尝试添加根级别节点(“修改”和“添加根级别”按钮)时,会出现问题。这些修改不应该反映在TreeView上,因为它与集合绑定了吗?

2 个答案:

答案 0 :(得分:2)

正如您现在所做的那样,Collection在更改时不会通知视图。您想使用ObservableCollection而不是普通的Collection<T>ObservableCollection已编码为与UI一起使用,并确保视图始终通过CollectionChanged事件更新。您可以将ObservableCollection用于其他一些,但您的Regions变量是Collection。

答案 1 :(得分:1)

您需要将Collection类型更改为ObservableCollection,并需要在区域类上实施INotifyPropertyChanged,以便在编辑时向View发送通知。

C# 窗口类:

ObservableCollection<Region> regions;

地区类别:

public class Region  : INotifyPropertyChanged
    { 
        public Region(string name) 
        { 
            Name = name; Type = new ObservableCollection<Types>(); 
        } 
        private string name;
                public string Name
        {
            get { return name; }
            set 
            { 
                name = value;
                PropertyChanged(this, new PropertyChangedEventArgs("Name"));
            }
        }

        public ObservableCollection<Types> Type { get; set; }

        #region INotifyPropertyChanged Members

        public event PropertyChangedEventHandler PropertyChanged = (s, e) => { };

        #endregion
    }