我有很多其是呈现昂贵的物品的列表框。然而,VirtualizingStackPanel只渲染可见的项目需要照顾那个。我想要替换的ScrollViewer控件模板,因为默认的一个具有水平和垂直滚动条之间的灰色矩形。我只是复制由微软(的ScrollViewer控件模板提供的一个实施例),其不具有灰色矩形问题。

此的ControlTemplate然而通过给予VirtualizingStackPanel无端高度禁用虚拟化。这意味着VirtualizingStackPanel将使所有项目,因为它认为所有的项目都可见。

在演示代码下面我显示在列表框10000项。我通过比较ScrollViewer中的风格,没有它运行它验证的问题。有了它演示的运行速度很慢,调整需要很多秒。没有风格它的速度非常快。 I输出有关VirtualizingStackPanel一些信息,以证明我的观点:

如果没有的ScrollViewer样式(注释列于XAML样式):

  

ViewportHeight:8,点击   ExtentHeight:10000次点击   的ActualHeight:245点击   IsVirtualizing:真正的结果   VirtualizationMode:标准

使用所述的ScrollViewer样式:

  

ViewportHeight:0,点击   ExtentHeight:0点击   的ActualHeight:272766.666666707结果   IsVirtualizing:真正的结果   VirtualizationMode:标准

不知道如何写一个ScrollViewer中一点不乱用虚拟化控制模板?

XAML:

<Window x:Class="VirtualTest.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">

    <Window.Resources>

        <Style x:Key="{x:Type ScrollViewer}" TargetType="{x:Type ScrollViewer}">
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ScrollViewer}">
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="Auto" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <ScrollContentPresenter Grid.Row="0" Grid.Column="0" />
                            <ScrollBar 
                                Name="PART_VerticalScrollBar" 
                                Grid.Row="0" Grid.Column="1" 
                                Value="{TemplateBinding VerticalOffset}" 
                                Maximum="{TemplateBinding ScrollableHeight}" 
                                ViewportSize="{TemplateBinding ViewportHeight}" 
                                Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" />
                            <ScrollBar 
                                Name="PART_HorizontalScrollBar" 
                                Orientation="Horizontal" 
                                Grid.Row="1" Grid.Column="0" 
                                Value="{TemplateBinding HorizontalOffset}" 
                                Maximum="{TemplateBinding ScrollableWidth}" 
                                ViewportSize="{TemplateBinding ViewportWidth}" 
                                Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

    </Window.Resources>

    <Grid>
        <ListBox 
            ItemsSource="{Binding Numbers}"
            ScrollViewer.ScrollChanged="ListBox_ScrollChanged"
            Background="Orange">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderBrush="Red" BorderThickness="2" Margin="5">
                        <TextBlock Text="{Binding .}" Width="400"/>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate> 
        </ListBox>

    </Grid>
</Window>

代码后面:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

namespace VirtualTest
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            DataContext = this;
        }

        public IEnumerable<double> Numbers
        {
            get
            {
                for (int i = 0; i < 10000; i++)
                {
                    yield return i;
                }
            }
        }

        private void ListBox_ScrollChanged(object sender, ScrollChangedEventArgs e)
        {
            ListBox listBox = sender as ListBox;
            VirtualizingStackPanel virtualizingStackPanel = FindVirtualizingStackPanel(listBox);                             
            Debug.WriteLine("ViewportHeight: " + virtualizingStackPanel.ViewportHeight);
            Debug.WriteLine("ExtentHeight: " + virtualizingStackPanel.ExtentHeight);
            Debug.WriteLine("ActualHeight: " + virtualizingStackPanel.ActualHeight);
            Debug.WriteLine("IsVirtualizing: " + VirtualizingStackPanel.GetIsVirtualizing(virtualizingStackPanel));
            Debug.WriteLine("VirtualizationMode: " + VirtualizingStackPanel.GetVirtualizationMode(virtualizingStackPanel));
        }

        private VirtualizingStackPanel FindVirtualizingStackPanel(Visual visual)
        {
            for (int i = 0; i < VisualTreeHelper.GetChildrenCount(visual); i++)
            {
                Visual child = VisualTreeHelper.GetChild(visual, i) as Visual;

                if (child != null)
                {
                    if (child is VirtualizingStackPanel)
                    {
                        return child as VirtualizingStackPanel;
                    }

                    VirtualizingStackPanel found = FindVirtualizingStackPanel(child);
                    if (found != null)
                    {
                        return found;
                    }
                }
            }

            return null;
        }
    }
}
有帮助吗?

解决方案

此的ScrollViewer样式从掺合物4中复制,它看起来良好在输出窗口

  

ViewportHeight:10,点击   ExtentHeight:10000次点击   的ActualHeight:308点击   IsVirtualizing:真正的结果   VirtualizationMode:标准

<Style TargetType="{x:Type ScrollViewer}">
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="false">
            <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
        </Trigger>
    </Style.Triggers>
    <Setter Property="Template" Value="{DynamicResource ScrollViewerControlTemplate1}"/>
</Style>
<ControlTemplate x:Key="ScrollViewerControlTemplate1" TargetType="{x:Type ScrollViewer}">
    <Grid x:Name="Grid" Background="{TemplateBinding Background}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Rectangle x:Name="Corner" Grid.Column="1" Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" Grid.Row="1"/>
        <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" CanContentScroll="{TemplateBinding CanContentScroll}" CanHorizontallyScroll="False" CanVerticallyScroll="False" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" Grid.Column="0" Margin="{TemplateBinding Padding}" Grid.Row="0"/>
        <ScrollBar x:Name="PART_VerticalScrollBar" AutomationProperties.AutomationId="VerticalScrollBar" Cursor="Arrow" Grid.Column="1" Maximum="{TemplateBinding ScrollableHeight}" Minimum="0" Grid.Row="0" Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}" Value="{Binding VerticalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportHeight}"/>
        <ScrollBar x:Name="PART_HorizontalScrollBar" AutomationProperties.AutomationId="HorizontalScrollBar" Cursor="Arrow" Grid.Column="0" Maximum="{TemplateBinding ScrollableWidth}" Minimum="0" Orientation="Horizontal" Grid.Row="1" Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}" Value="{Binding HorizontalOffset, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}}" ViewportSize="{TemplateBinding ViewportWidth}"/>
    </Grid>
</ControlTemplate>
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top