2013-03-23 27 views
6

Tôi muốn người dùng có thể tìm kiếm các mục trong TreeView. Sau khi nhập văn bản tìm kiếm, TreeViewItem sẽ được cuộn vào chế độ xem.TreeView BringIntoView với MVVM

Hiện tại tôi đang sử dụng Mẫu MVVM cho TreeView, cho TreeViewItems và MainView.

Tôi phải làm gì để có được chức năng của BringIntoView sử dụng MVVM? Có một số tài sản tôi có thể ràng buộc không? (trong MFC có một cái gì đó giống như FirstVisibileItem)

Đã thấy một "giải pháp" với một hành vi. Có thực sự cần thiết không?

+0

Tôi nghĩ MVVM nên dừng lại ở khái niệm "lựa chọn". Nếu điều đó không di chuyển mục vào chế độ xem, tôi sẽ sử dụng các sự kiện thông thường trong Chế độ xem. –

+1

Bạn nói đúng, chế độ xem không nên quan tâm đến chế độ xem. Nhưng đây là một số trường hợp đặc biệt mà là "ở biên giới" của MVVM tôi tin. –

+0

Máy ảo sẽ chỉ ra một mục nhất định, nhưng đó là nó. Các vấn đề cuộn được xử lý tốt hơn trong Chế độ xem. –

Trả lời

5

Sự cố có thể được giải quyết bằng Hành vi.

Điều này CodeProject article mô tả nó rất tốt và nó hoạt động ra khỏi hộp.

8

Theo bài viết Dự án mã đã đề cập, đây là ví dụ về Mã cho thấy cách thiết lập Hành vi và cách tích hợp Hành vi trong XAML.

cài đặt hành vi:

/// <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 
} 

Sau đó tích hợp các TreeViewItemBehavior trong XAML:

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

Hãy vui vẻ :-)

+0

Các setter cho tài sản phụ thuộc không được áp dụng cho các mục trong treeview của tôi cho đến khi chúng được hiển thị bằng cách mở rộng chúng. Do đó, TreeViewItem.Selected không có sự kiện được đính kèm ban đầu. Nếu tôi có mã lập trình mở rộng các nút và chọn một nút sâu trong cây, nó sẽ không được đưa vào xem. – DannyMeister

+0

Tìm thấy giải pháp cho trường hợp cụ thể của tôi. Nếu thuộc tính phụ thuộc đang được bật, thì điều đó có ý nghĩa đối với tôi để tiếp tục và cuộn đến mục nếu nó đã được chọn. Bên trong if, sau dòng: 'item.Selected + = OnTreeViewItemSelected;' Tôi đã thêm: 'if (item.IsSelected) {item.RaiseEvent (new RoutedEventArgs (TreeViewItem.SelectedEvent)); } ' – DannyMeister

+0

Đó không phải là một hành vi, đó là một phần mở rộng. TreeViewItem * Hành vi * – Snicker