2013-03-23 57 views
6

我希望用戶能夠搜索TreeView中的項目。 輸入搜索文本後,TreeViewItem應滾動到視圖中。TreeView BringIntoView與MVVM

現在我正在使用MVVM模式的TreeView,爲TreeViewItems和MainView。

如何使用MVVM獲得BringIntoView的功能我需要做些什麼? 有一些我可以綁定的屬性嗎? (在MFC中有類似於FirstVisibileItem的東西)

已經看到了具有行爲的「解決方案」。它真的有必要嗎?

+0

我覺得MVVM應在 「選擇」 的概念停止。如果這不會將項目滾動到視圖中,我會在視圖中使用常規事件。 – 2013-03-23 13:03:05

+1

你說得對,viewmodel不應該關心這個視圖。但這裏有一些特殊情況,我相信MVVM的「邊界」。 – 2013-03-23 13:57:22

+0

虛擬機應該指明某個項目,但就是這樣。滾動問題最好在View中處理。 – 2013-03-23 14:25:51

回答

5

該問題可以通過行爲來解決。

這個CodeProject article描述非常好,它開箱即用。

8

根據上述代碼項目文章,以下是代碼示例,演示如何設置行爲以及如何將行爲集成到XAML中。

設置的行爲:

/// <summary> 
/// Exposes attached behaviors that can be 
/// applied to TreeViewItem objects. 
/// </summary> 
public static class TreeViewItemBehavior 
{ 
    #region IsBroughtIntoViewWhenSelected 
    public static bool GetIsBroughtIntoViewWhenSelected(TreeViewItem treeViewItem) 
    { 
     return (bool)treeViewItem.GetValue(IsBroughtIntoViewWhenSelectedProperty); 
    } 

    public static void SetIsBroughtIntoViewWhenSelected(  TreeViewItem treeViewItem, bool value) 
    { 
     treeViewItem.SetValue(IsBroughtIntoViewWhenSelectedProperty, value); 
    } 

    public static readonly DependencyProperty IsBroughtIntoViewWhenSelectedProperty = 
    DependencyProperty.RegisterAttached(
    "IsBroughtIntoViewWhenSelected", 
    typeof(bool), 
    typeof(TreeViewItemBehavior), 
    new UIPropertyMetadata(false, OnIsBroughtIntoViewWhenSelectedChanged)); 

    static void OnIsBroughtIntoViewWhenSelectedChanged(DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
    { 
     TreeViewItem item = depObj as TreeViewItem; 
     if (item == null) 
      return; 

     if (e.NewValue is bool == false) 
      return; 

     if ((bool)e.NewValue) 
      item.Selected += OnTreeViewItemSelected; 
     else 
      item.Selected -= OnTreeViewItemSelected; 
    } 

    static void OnTreeViewItemSelected(object sender, RoutedEventArgs e) 
    { 
     // Only react to the Selected event raised by the TreeViewItem 
     // whose IsSelected property was modified. Ignore all ancestors 
     // who are merely reporting that a descendant's Selected fired. 
     if (!Object.ReferenceEquals(sender, e.OriginalSource)) 
     return; 

     TreeViewItem item = e.OriginalSource as TreeViewItem; 
     if (item != null) 
      item.BringIntoView(); 
    } 

    #endregion // IsBroughtIntoViewWhenSelected 
} 

然後在XAML集成TreeViewItemBehavior:

<TreeView.ItemContainerStyle> 
    <Style TargetType="{x:Type TreeViewItem}"> 
    <Setter Property="local:TreeViewItemBehavior.IsBroughtIntoViewWhenSelected" Value="True"/> 
    </Style> 
</TreeView.ItemContainerStyle> 

玩得開心:-)

+0

依賴項屬性的設置不適用於我的樹視圖中的項目直到它們通過擴展它們變得可見。因此,TreeViewItem.Selected最初沒有附加事件。如果我有以編程方式展開節點並在樹中選擇一個深層的代碼,它不會被顯示。 – DannyMeister 2016-05-25 19:32:25

+0

爲我的具體情況找到了一個解決方案。如果啓用了依賴項屬性,那麼對於我來說,如果它已被選中,則滾動到該項目是有意義的。在if後面,行後面:'item.Selected + = OnTreeViewItemSelected;'我加了:'if(item.IsSelected){item.RaiseEvent(new RoutedEventArgs(TreeViewItem.SelectedEvent)); }' – DannyMeister 2016-05-25 21:36:59

+0

這不是一種行爲,這是一個擴展。樹型視圖* *行爲 – Snicker 2016-09-07 15:55:15