2011-02-25 17 views
2

在我的MVVM應用程序中,我有一個樹視圖,應該將treeviewitem帶入選定視圖。樹視圖表示數據庫中的記錄。每個樹視圖項都會在需要時通過擴展項來加載它的子項。wpf TreeViewItem BringIntoView並不總是工作

樹形視圖風格的定義是這樣的:

<TreeView.ItemContainerStyle> 
    <Style TargetType="{x:Type TreeViewItem}"> 
     <Setter Property="OverridesDefaultStyle" Value="True"/> 
     ... 
     <EventSetter Event="Selected" Handler="OnTreeViewItemSelected"/> 

處理程序是這樣定義的:

private void OnTreeViewItemSelected(object sender, RoutedEventArgs e) 
{ 
    if (!Object.ReferenceEquals(sender, e.OriginalSource)) 
    { 
    return; 
    } 
    TreeViewItem item = e.OriginalSource as TreeViewItem; 
    if (item != null) 
    {   
    EventHandler eventHandler = null; 
    eventHandler = new EventHandler(delegate 
    { 
     treeData.LayoutUpdated -= eventHandler; 
     item.BringIntoView(); 
    }); 
    treeData.LayoutUpdated += eventHandler; 
    } 
} 

這工作得很好爲那些已經加載的項目。

[編輯:其實所選項目的母公司必須擴大而不是僅僅加載]

如果它們被加載時,treeviewitems被重複直到尋求項目被找到,找到的項目被選中,上面的處理程序成功將其引入視圖。

問題在於尚未加載的項目。在這些情況下,我的代碼獲取搜索項目的祖先記錄,遍歷它們擴展項目(因此會加載子項)直到它到達所需項目。這是成功選擇,但不會被引入視圖。

有誰知道如何解決這個問題?

[UPDATE] 在TreeViewItemViewModel:

public bool IsSelected 
{ 
    get { return _isSelected; } 
    set 
    {   
    if (value != _isSelected) 
    {   
     _isSelected = value; 

     if (value == true)   
     IsExpanded = value;   

     this.OnPropertyChanged("IsSelected"); 
    } 
    } 
} 

public bool IsExpanded 
{ 
    get { return _isExpanded; } 
    set 
    { 
    if (_isExpanded == value) 
     return; 

    _isExpanded = value; 
    this.OnPropertyChanged("IsExpanded"); 

    if (_isExpanded && 
     _parent != null && 
     _parent.IsExpanded == false) 
     _parent.IsExpanded = true; 

    LoadChildren(); 
    } 
} 

LoadChildren()方法處理的孩子是否需要加載或不使用的標誌。

ItemContainerStyle

setter屬性= 「IsExpanded」 VALUE = 「{結合IsExpanded,模式=雙向}」 setter屬性= 「IsSelected」 VALUE = 「{結合IsSelected,模式=雙向}」

+0

可否請您發佈更多關於itemcontainerstyle的IsSelected和IsExpanded屬性的代碼。此外,代碼是在cs端isselected和isexpanded,還有一些關於如何加載子樹並表示它們已加載的代碼 – 2011-03-01 10:29:22

回答

0

好的,所以我似乎已經通過'意外'解決了這個問題。

如果我運行在所選擇的後臺進程搜索它被帶入視圖

public void Search() 
{ 
    ImplementSearch(); 

    _workinghelper = new WorkingHelper(); 
    SearchWorkingViewModel searchvm = new SearchWorkingViewModel(_workinghelper.WorkingWindow); 
    VisualUtils.FadeTreeViewItemViewModel(1.0, 0.2, 0, 100); 
    _workinghelper.MakeWorking(searchvm); 

    VisualUtils.FadeTreeViewItemViewModel(0.2, 1.0, 0, 001); 
} 

public bool CanSearch 
{ 
    get { return _searchlogic.SearchTypeIsValid(_searchterm); } 
} 

void ImplementSearch() 
{  
    BackgroundTaskManager.RunBackgroundTask(
    () => 
    { 
     bool run_success = _searchlogic.PerformSearch(_searchterm); 
     Thread.Sleep(500); 
     return run_success; 
    }, 
    (run_success) => 
    { 
     if (run_success == false) 
     ApplicationSetup.DisableApp((MainWindow)App.Current.MainWindow, "The search function has caused an unexpected internal error. Please contact an administrator for help."); 

     if (_workinghelper != null) 
     _workinghelper.DisposeWorkingWindow(); 
    });  
} 

但是,如果我只需運行 布爾run_success = _searchlogic.PerformSearch(_searchterm); ImplementSearch()中的 項目不會被帶入視圖。

3

this可能會解決你的問題

,並建立在this一篇關於使用MVVM爲一個TreeView

編輯: 也有您的treeviewitem容器尚未創建的可能性。那麼你必須撥動TreeViews ItemContainerGenerator

+0

是的,我已經爲TreeView實現了MVVM,並使用了TreeViewItemBehaviour附加屬性,仍然是問題仍在。我會檢查出ItemContainerGenerator ... – pilsdumps 2011-02-26 13:45:33

+0

我還在爲此而苦苦掙扎。我已經嘗試了其他兩個解決方案https://gist.github.com/755546#file_tree_view_item_finder.cs,但仍然是這個問題。請注意編輯 - 實際上,如果父代已加載,然後摺疊,則該項目將被選中,但不會顯示 – pilsdumps 2011-03-01 09:51:41