2014-02-20 3 views
0

Я пишу прикрепленное поведениеWPF Treeview Items Visibility Прикрепленного поведение

public class resizingBehavior : Behavior<ItemsControl>

, чтобы определить количество видимых элементов в TreeView.

В методе OnAttached

protected override void OnAttached() 
{ 
    base.OnAttached(); 
    AssociatedObject.Loaded += AssociatedObject_Loaded; 
} 

Внутри AssociatedObject.Loaded обработчик события

Я закреплять на размер измененную обработчик событий для моего управления TreeView

private void AssociatedObject_Loaded(object sender, RoutedEventArgs e) 
{ 
    var itemsControl = (ItemsControl)sender; 

    _sizeChangedEventHandler = (s, f) => ComputeVisibleItemsCount(itemsControl); 

    var treeListView = AssociatedObject as TreeListView;   
    treeListView.SizeChanged += _sizeChangedEventHandler; 

    itemsControl.Loaded -= AssociatedObject_Loaded; 
} 

Эти события вызывается, когда я загружаю мой приложение и когда я изменяю размер моего дерева. Моя проблема заключается в вычислении видимых элементов внутри древовидной структуры. К сожалению, свойство IsVisible не дает мне правильного результата. Я использовал ответ, предложенный в In WPF, how can I determine whether a control is visible to the user?

Но это не работает для меня. Это дает мне неправильный результат.

Любая хорошая практика или стандартное решение для определения фактических видимых элементов в элементах управления? при изменении размера и прокрутке? Кстати, я использую реактивную коллекцию для своих элементов treeview.

ответ

0

Это рабочее решение. Любой желающий может реорганизовать и исправить код.

[Localizable(false)] 
public class ItemsControlResizingBehavior : Behavior<ItemsControl> 
{ 
    public static readonly DependencyProperty VisibleItemsCountProperty = 
     DependencyProperty.Register("VisibleItemsCount", 
      typeof(int), 
      typeof(ItemsControlResizingBehavior), 
      new FrameworkPropertyMetadata(0, OnSizeChanged)); 

    public int VisibleItemsCount 
    { 
     get { return (int)GetValue(VisibleItemsCountProperty); } 
     set { SetValue(VisibleItemsCountProperty, value); } 
    } 

    private static void OnSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     if (e.NewValue == null) 
      return; 
     var behavior = (ItemsControlResizingBehavior)d; 

     if (behavior.AssociatedObject == null) 
      return; 

     behavior.ComputeVisibleItemsCount(behavior.AssociatedObject); 
    } 

    private SizeChangedEventHandler _listViewSizeChangedEventHandler; 

    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     AssociatedObject.Loaded += AssociatedObject_Loaded; 
    } 

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e) 
    { 
     var itemsControl = (ItemsControl)sender; 

     _listViewSizeChangedEventHandler = (x, y) => ComputeVisibleItemsCount(itemsControl); 

     var treeListView = AssociatedObject as TreeListView; 
     if (treeListView != null) 
      treeListView.SizeChanged += _listViewSizeChangedEventHandler; 

     var listView = AssociatedObject as ListView; 
     if (listView != null) 
      listView.SizeChanged += _listViewSizeChangedEventHandler; 

     itemsControl.Loaded -= AssociatedObject_Loaded; 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 

     var treeListView = AssociatedObject as TreeListView; 
     if (treeListView != null) 
      treeListView.SizeChanged -= _listViewSizeChangedEventHandler; 

     var listView = AssociatedObject as ListView; 
     if (listView != null) 
      listView.SizeChanged -= _listViewSizeChangedEventHandler; 
    } 

    private void ComputeVisibleItemsCount(ItemsControl itemsControl) 
    { 
     if (itemsControl.Items.Count <= 0) 
      return; 

     if (itemsControl is TreeListView) 
     { 
      VisibleItemsCount = GetTreeViewItems(itemsControl).Count(x => x.IsVisibleInUI(itemsControl)); 
     } 
     if (itemsControl is ListView) 
     { 
      VisibleItemsCount = GetListViewItems(itemsControl).Count(x => x.IsVisibleInUI(itemsControl)); 
     } 
    } 

    private static IEnumerable<TreeViewItem> GetTreeViewItems(ItemsControl tree) 
    { 
     for (int i = 0; i < tree.Items.Count; i++) 
     { 
      var item = (TreeViewItem)tree.ItemContainerGenerator.ContainerFromIndex(i); 
      if (item == null) 
       continue; 

      yield return item; 

      foreach (TreeViewItem subItem in GetTreeViewItems(item)) 
      { 
       yield return subItem; 
      } 
     } 
    } 

    private static IEnumerable<ListViewItem> GetListViewItems(ItemsControl list) 
    { 
     for (int i = 0; i < list.Items.Count; i++) 
     { 
      var item = (ListViewItem)list.ItemContainerGenerator.ContainerFromIndex(i); 
      if (item == null) 
       continue; 

      yield return item; 
     } 
    } 
}