Set XAML ListBox MaxHeight to height of 10 rows

Sam of Simple Samples 5,516 Reputation points
2023-10-24T01:37:51.26+00:00

How can I set the height (MaxHeight) of a ListBox to the height of a specified number of rows, such as 10? Either in XAML or in code-behind. This is for WPF.

It seems to be a very simple requirement and should be a common one but I cannot find anything to help. I cannot even find what the height is of the rows during execution.

XAML
XAML
A language based on Extensible Markup Language (XML) that enables developers to specify a hierarchy of objects with a set of properties and logic.
765 questions
0 comments No comments
{count} votes

1 answer

Sort by: Most helpful
  1. gekka 6,591 Reputation points MVP
    2023-10-24T09:38:21.1833333+00:00
    <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));
        }
    }