我需要一個TreeView
來表示存儲在SQL Server CE數據庫中的多個表的一些分層數據。之前,數據存儲在xml中,在啓動時很簡單的反序列化,一切都很好。現在我被要求將數據移動到數據庫,並且遇到了幾個問題。如何在延遲加載的WPF MVVM TreeView中搜索?
我的第一個問題是,從數據庫中檢索多個項目並從這些項目構建一個TreeView ViewModel需要相當長的時間(仍然不確定什麼是更長的時間 - 獲取項目或構建此樹)。所以我實現了延遲加載,現在只有在TreeViewItem
正在擴展時我纔會收到項目。
現在,我需要對所有節點執行文本搜索,但要使其工作,必須加載所有節點。 我試圖加載所有這些,但樹加載時UI凍結。在BackgroundWorker
內部執行此操作對我來說也是不可能的,因爲這些項目存儲在ObservableCollection
中,我得到「InvalidOperationException」。使用Dispatcher
有助於此,但它也凍結UI ...
從我的TreeViewItem
虛擬機的摘錄如下,如果需要更多的代碼,請讓我知道。也許我對我的設計完全錯誤,所以任何意見都非常感謝!
public class TreeViewItemViewModel: DisplayableItem, IItemsHost
{
internal static DummyTreeViewItemViewModel _dummy = new DummyTreeViewItemViewModel();
public TreeViewItemViewModel(){}
public TreeViewItemViewModel(IDisplayableItem displayableItem)
{
Data = displayableItem;
}
public TreeViewItemViewModel(IDisplayableItem displayableItem, IDisplayableItem parent)
:this(displayableItem)
{
Parent = parent as TreeViewItemViewModel;
}
private TreeViewItemViewModel _parent;
public TreeViewItemViewModel Parent
{
get { return _parent; }
set { _parent = value; InvokePropertyChanged(new PropertyChangedEventArgs("Parent")); }
}
private IDisplayableItem _data;
public new IDisplayableItem Data
{
get { return _data; }
set { _data = value; InvokePropertyChanged(new PropertyChangedEventArgs("Data")); }
}
private bool _isSelected;
public new bool IsSelected
{
get { return _isSelected; }
set { _isSelected = value; InvokePropertyChanged(new PropertyChangedEventArgs("IsSelected")); }
}
private bool _isEnabled=true;
public new bool IsEnabled
{
get { return _isEnabled; }
set { _isEnabled = value; InvokePropertyChanged(new PropertyChangedEventArgs("IsEnabled")); }
}
private bool _isVisible = true;
public new bool IsVisible
{
get { return _isVisible; }
set { _isVisible = value; InvokePropertyChanged(new PropertyChangedEventArgs("IsVisible")); }
}
private void FillItems()
{
if (Items.Contains(_dummy))
{
Items.Remove(_dummy);
var itemshost = Data as IItemsHost;
if (itemshost != null)
{
_items = new ObservableCollection<IDisplayableItem>();
foreach (var item in itemshost.Items)//getting 'Items' actually requesting them from a database
{
var treeItem = new TreeViewItemViewModel(item, this);
_items.Add(treeItem);
}
InvokePropertyChanged(new PropertyChangedEventArgs("Items"));
}
}
}
protected bool _isExpanded;
public bool IsExpanded
{
get { return _isExpanded; }
set
{
if(value)
{
FillItems();
}
_isExpanded = value;
InvokePropertyChanged(new PropertyChangedEventArgs("IsExpanded"));
}
}
protected SObservableCollection<IDisplayableItem> _items = new SObservableCollection<IDisplayableItem>();
public SObservableCollection<IDisplayableItem> Items
{
get
{
var itemshost = Data as IItemsHost;
if (itemshost != null)
{
if (_items.Count == 0 && itemshost.Items.Count > 0)
_items.Add(_dummy);
}
return _items;
}
set { _items = value; InvokePropertyChanged(new PropertyChangedEventArgs("Items")); }
}
更新:對於那些誰也尋找一個類似的解決方案 - 我的問題是在我的查詢方法。每當我需要執行查詢時,我都不應該打開新的SQL Server CE連接...
我已經使用'System.Diagnostics.Stopwatch'做了一個簡單的測試,發現即使不使用視圖(在控制檯應用程序中),迭代所有樹項目和子項目需要大約30秒,並填充它們全部。這不好,但我不知道該怎麼做這:( – lena 2015-02-12 07:25:34