【问题标题】:WPF Treeview Items Visibility Attached behaviorWPF 树视图项目可见性附加行为
【发布时间】:2014-03-21 04:58:03
【问题描述】:

我正在写一个附加的行为

public class resizingBehavior : Behavior<ItemsControl>

确定树视图中可见项目的数量。

在 OnAttached 方法中

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

AssociatedObject.Loaded 事件处理程序内部

我正在为我的树视图控件挂钩一个大小更改的事件处理程序

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?中建议的答案

但这似乎对我不起作用。它给了我一个错误的结果。

确定项目控件中实际可见项目的任何良好做法或标准解决方案?调整大小和滚动时?顺便说一句,我正在为我的树视图项目使用响应式集合。

【问题讨论】:

    标签: c# wpf xaml mvvm treeview


    【解决方案1】:

    这是有效的解决方案。欢迎任何人重构和更正代码。

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

    【讨论】:

      猜你喜欢
      • 2013-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 2016-04-24
      • 1970-01-01
      • 2015-01-28
      相关资源
      最近更新 更多