2013-03-23 188 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