<Window x:Class="Gekka.WpfApplication1.MainWindow2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Gekka.WpfApplication1"
mc:Ignorable="d"
Title="MainWindow2" Height="400" Width="200">
<DockPanel>
<Slider x:Name="slider1" DockPanel.Dock="Bottom" Minimum="10" Value="20" Maximum="50" />
<ListBox ItemsSource="{Binding}"
ScrollViewer.CanContentScroll="True" FontSize="8"
VerticalAlignment="Top">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<local:VirtualizingStackPanelEx
ViewCountLimit="10"
Orientation="Vertical" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="Height" Value="{Binding ElementName=slider1,Path=Value}" />
<Setter Property="BorderBrush" Value="Black" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Margin" Value="1" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</DockPanel>
</Window>
namespace Gekka.WpfApplication1
{
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
public partial class MainWindow2 : Window
{
public MainWindow2()
{
InitializeComponent();
this.DataContext = Enumerable.Range(1, 100).ToArray();
}
}
class VirtualizingStackPanelEx : VirtualizingStackPanel
{
protected override Size ArrangeOverride(Size arrangeSize)
{
var sz = base.ArrangeOverride(arrangeSize);
ArrangeScrollViewer();
return sz;
}
private void ArrangeScrollViewer()
{
if (ScrollOwner == null)
{
return;
}
int count = 0;
double length = 0;
int limit = Math.Max(ViewCountLimit, 0);
for (int i = 0; i < this.Children.Count && count < limit; i++)
{
if (this.Children[i] is FrameworkElement fe)
{
var p = fe.TranslatePoint(new Point(0, 0), this);
if (this.Orientation == Orientation.Vertical)
{
if (p.Y >= 0)
{
length += fe.ActualHeight + fe.Margin.Top + fe.Margin.Bottom;
count++;
}
}
else
{
if (p.X >= 0)
{
length += fe.ActualWidth + fe.Margin.Left + fe.Margin.Right;
count++;
}
}
}
}
if (this.Orientation == Orientation.Vertical)
{
ScrollOwner.MaxHeight = length;
ScrollOwner.MaxWidth = double.PositiveInfinity;
}
else
{
ScrollOwner.MaxHeight = double.PositiveInfinity;
ScrollOwner.MaxWidth = length;
}
}
public int ViewCountLimit
{
get { return (int)GetValue(ViewCountLimitProperty); }
set { SetValue(ViewCountLimitProperty, value); }
}
public static readonly DependencyProperty ViewCountLimitProperty
= DependencyProperty.Register("ViewCountLimit", typeof(int), typeof(VirtualizingStackPanelEx)
, new FrameworkPropertyMetadata((int)1, FrameworkPropertyMetadataOptions.AffectsArrange));
}
}