为什么我的第二个 ObservableCollection 正在更新?
Why my second ObservableCollection is getting update?
我有两个个填充了相同类型的Items的ObservableCollections(那个Items也是填充了其他类型对象的ObservableCollecions)。
_TreeViewBase - 第一个 ObservableCollection 'base' 包含所有数据。
_TVData - 第二个 ObservableCollection 应该只存储 'needed' 个项目,我还有 TreeView 和 ItemSource 绑定到 TVData。
函数FillAliasTreeView 仅用于用数据填充_TreeViewBase,因此我不会在此处粘贴代码。
在程序开始时,我在 LoadSideBar() 函数中 assign _TreeViewBase 到 _TVData 一切正常。
两个 ObservableCollection 都在存储所有数据。
但是当我搜索某些东西时(并且我的 TVData 在 SearchBox_TextChanged() 中被修改)然后看起来
_TreeViewBase 也被修改。
怎么可能?我的代码是否犯了一些重大错误?
我的class(几乎完整的代码):
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();
}
}
感谢您的任何建议。
在您的构造函数中,您将 TVData
和 TreeViewBase
设置为 ObservableCollection<>
的两个不同实例。但是接下来这一行:
TVData = TreeViewBase;
使它们引用 相同的 实例。旧的 TVData
observable 集合被丢弃,这两个变量现在都引用同一个 observable 集合。
我有两个个填充了相同类型的Items的ObservableCollections(那个Items也是填充了其他类型对象的ObservableCollecions)。
_TreeViewBase - 第一个 ObservableCollection 'base' 包含所有数据。
_TVData - 第二个 ObservableCollection 应该只存储 'needed' 个项目,我还有 TreeView 和 ItemSource 绑定到 TVData。
函数FillAliasTreeView 仅用于用数据填充_TreeViewBase,因此我不会在此处粘贴代码。
在程序开始时,我在 LoadSideBar() 函数中 assign _TreeViewBase 到 _TVData 一切正常。 两个 ObservableCollection 都在存储所有数据。
但是当我搜索某些东西时(并且我的 TVData 在 SearchBox_TextChanged() 中被修改)然后看起来 _TreeViewBase 也被修改。
怎么可能?我的代码是否犯了一些重大错误?
我的class(几乎完整的代码):
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();
}
}
感谢您的任何建议。
在您的构造函数中,您将 TVData
和 TreeViewBase
设置为 ObservableCollection<>
的两个不同实例。但是接下来这一行:
TVData = TreeViewBase;
使它们引用 相同的 实例。旧的 TVData
observable 集合被丢弃,这两个变量现在都引用同一个 observable 集合。