WPF ListBox with a ListBox - UI Virtualization and Scrolling

前端 未结 5 1012
执笔经年
执笔经年 2020-11-28 03:03

My prototype displays \"documents\" that contain \"pages\" that are represented by thumbnail images. Each document can have any number of pages. For example, there might be

5条回答
  •  执念已碎
    2020-11-28 03:43

    It is possible to achieve smooth scrolling VirtualizingStackPanels in WPF 4.0 without sacrificing virtualization if you're prepared to use reflection to access private functionality of the VirtualizingStackPanel. All you have to do is set the private IsPixelBased property of the VirtualizingStackPanel to true.

    Note that in .Net 4.5 there's no need for this hack as you can set VirtualizingPanel.ScrollUnit="Pixel".

    To make it really easy, here's some code:

    public static class PixelBasedScrollingBehavior 
    {
        public static bool GetIsEnabled(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsEnabledProperty);
        }
    
        public static void SetIsEnabled(DependencyObject obj, bool value)
        {
            obj.SetValue(IsEnabledProperty, value);
        }
    
        public static readonly DependencyProperty IsEnabledProperty =
            DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(PixelBasedScrollingBehavior), new UIPropertyMetadata(false, HandleIsEnabledChanged));
    
        private static void HandleIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var vsp = d as VirtualizingStackPanel;
            if (vsp == null)
            {
                return;
            }
    
            var property = typeof(VirtualizingStackPanel).GetProperty("IsPixelBased",
                                                                         BindingFlags.NonPublic | BindingFlags.Instance);
    
            if (property == null)
            {
                throw new InvalidOperationException("Pixel-based scrolling behaviour hack no longer works!");
            }
    
            if ((bool)e.NewValue == true)
            {
                property.SetValue(vsp, true, new object[0]);
            }
            else
            {
                property.SetValue(vsp, false, new object[0]);
            }
        }
    }
    

    To use this on a ListBox, for example, you would do:

    
       
          
             
              
           
       
    
    

提交回复
热议问题