2014-02-20 3 views
0

나는 트 리뷰에 표시되는 항목의 수를 결정하기 위해 부착 행동WPF 트 리뷰 항목 가시성 첨부 행동

public class resizingBehavior : Behavior<ItemsControl>

을 쓰고 있어요. OnAttached 방법에

내가로드 할 때이 이벤트가 호출되는

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

내 트 리뷰 컨트롤의 크기 변경 이벤트 핸들러를 후킹하고있어

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

이벤트 핸들러 AssociatedObject.Loaded을 내 애플 리케이션과 때 내 treeview의 크기를 조정. 내 문제는 treeview 내부에 보이는 항목의 계산에 있습니다. 불행히도 IsVisible 속성은 올바른 결과를주지 못합니다. In WPF, how can I determine whether a control is visible to the user?

에 나와있는 답변을 사용했지만 그게 효과가없는 것 같습니다. 그것은 나에게 잘못된 결과를 준다.

itemscontrol에서 실제 볼 수있는 항목을 확인하기위한 우수 사례 또는 표준 해결책은 무엇입니까? 크기 조정 및 스크롤 할 때? 그건 그렇고 내 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; 
     } 
    } 
}