为什么我的第二个ObservableCollection正在更新?

Wik*_*tor 0 c# wpf treeview observablecollection treeviewitem

我有两个 ObservableCollections填充了相同类型的Items(Items也是ObservableCollecions,其中包含其他类型的对象).

_TreeViewBase - First ObservableCollection是所有数据的"基础".

_TVData - 第二个ObservableCollection应该只存储' required '项目,我还有TreeView,ItemSource绑定到TVData.

函数FillAliasTreeView仅用于使用数据填充_TreeViewBase,因此我不会在此处粘贴代码.

在程序开始时我 _TreeViewBase 分配给LoadSideBar()函数中的_TVData,一切正常.两个ObservableCollection都存储所有数据.

但是当我搜索某些内容(并且我的TVData在SearchBox_TextChanged()中被修改)时,似乎也修改了_TreeViewBase.

怎么可能?我在代码中犯了一些重大错误吗?

我的班级(几乎完整的代码):

public partial class SideBar : Page, INotifyPropertyChanged
{
    private ObservableCollection<ConnectionModel> _TreeViewBase;
    private ObservableCollection<ConnectionModel> _TVData ;



    public SideBar()
    {
        TreeViewBase = new ObservableCollection<ConnectionModel>( ConnectionUtilities.LoadObservableConnections() ) ;
        TVData       = new ObservableCollection<ConnectionModel>();

        InitializeComponent();


        DataContext = this;

        var loadSideBar = Task.Factory.StartNew( async () => { await LoadSideBar();   } );
        loadSideBar.Wait();

        OnPropertyChanged("TVData");
    }


    public async Task LoadSideBar()
    {
        // this function is used to fill my _TreeViewBase  
        await FillAliasTreeView();

        TVData = TreeViewBase;
        OnPropertyChanged("TVData");

    }

     private async void SearchBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        string newsearchText = SearchBox.Text;

        if ( (newsearchText == "" || newsearchText == "Search..." || newsearchText.Length < 3  )  ) 
        {

            TVData.Clear();
            TVData = null;

            MessageBox.Show( (TVData == null).ToString() + " " + TreeViewBase.Count.ToString());


            TVData = new ObservableCollection<ConnectionModel>( TreeViewBase );

            AliasTree.ItemsSource = TVData ;

            AliasTree.UpdateLayout();

            return;
        }

        searchText = SearchBox.Text;


        if (TVData != null)
        {
            await Dispatcher.InvokeAsync(
            () =>
            {
                foreach (ConnectionModel cm in TVData.ToList<ConnectionModel>())
                {
                    foreach (SchemaModel sm in cm.schemas.ToList<SchemaModel>())
                    {
                        foreach (SchemaCollection sc in sm.schema_collections.ToList<SchemaCollection>())
                        {
                            try
                            {
                                ObservableCollection<TableModel> octm = (ObservableCollection<TableModel>)sc.collection;

                                for (int i = 0; i < octm.Count; i++)
                                {
                                    if (!(sc.collection as ObservableCollection<TableModel>)[i].TABLE_NAME.Contains(searchText))
                                    {
                                        (sc.collection as ObservableCollection<TableModel>).RemoveAt(i);
                                        i = i - 1;
                                    }
                                    Dispatcher.InvokeAsync( () => OnPropertyChanged("tables") ) ;
                                }
                                Dispatcher.InvokeAsync(() => OnPropertyChanged("collection") );
                            }
                            catch (Exception exc) { }
                        }
                        Dispatcher.InvokeAsync(() => OnPropertyChanged("schemas") );
                    }
                    Dispatcher.InvokeAsync(() => OnPropertyChanged("TVData"));
                }
                Dispatcher.InvokeAsync(() => OnPropertyChanged("TVData"));
            });

            await Dispatcher.InvokeAsync(() => ExpandAll(AliasTree));
        }
    }


    private void ExpandAll( ItemsControl root )
    {
        if ( root != null )
        {
            foreach (var subItem in root.Items)
            {
                if (subItem != null)
                {
                    ExpandAll( (TreeViewItem)root.ItemContainerGenerator.ContainerFromItem(subItem) );
                    try
                    {
                        if (((TreeViewItem)root.ItemContainerGenerator.ContainerFromItem(subItem) as TreeViewItem) != null )
                            ((TreeViewItem)root.ItemContainerGenerator.ContainerFromItem(subItem) as TreeViewItem).IsExpanded = true;
                    }
                    catch (Exception exc) { };
                }
            }

            AliasTree.UpdateLayout();
        }
    }
Run Code Online (Sandbox Code Playgroud)

谢谢你的任何建议.

Ste*_*ary 5

在你的构造,可以设置TVDataTreeViewBase以两个不同的实例ObservableCollection<>.但接下来这行:

TVData = TreeViewBase;
Run Code Online (Sandbox Code Playgroud)

使它们引用同一个实例.旧的TVData可观察集合被丢弃,这两个变量现在都引用相同的可观察集合.

这就是引用类型的工作方式.