如何根据WPF中ListBox的高度显示项目?

时间:2017-11-09 07:01:36

标签: c# wpf listbox horizontal-scrolling

我将大约100个项目绑定到ListBox。这些项目垂直显示如下:

<ListBox x:Name="lstfolder4"  Grid.Row="7" Grid.ColumnSpan="2"  Grid.Column="0" SelectionMode="Multiple" >
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox  Content="{Binding Content}" IsChecked="{Binding IsChecked ,Mode=TwoWay}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

Items arranged vertically

但我希望它能横向显示。在谷歌搜索后,我尝试了下面的代码:

<ListBox x:Name="lstfolder2" Grid.Row="3" Grid.ColumnSpan="2" Grid.Column="0" SelectionMode="Multiple" >
    <ListBox.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel  IsItemsHost="True" Orientation="Horizontal"/>
        </ItemsPanelTemplate>
    </ListBox.ItemsPanel>
    <ListBox.ItemTemplate>
        <DataTemplate>
            <CheckBox  Content="{Binding Content}" Width="150" IsChecked="{Binding IsChecked ,Mode=TwoWay}"/>
        </DataTemplate>
    </ListBox.ItemTemplate>          
</ListBox>

现在显示如下。但我想在一列中显示4行。任何人都能帮助我吗?

Items arranged horizontally

提前致谢。

1 个答案:

答案 0 :(得分:3)

听起来像UniformGrid的完美用例:

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <UniformGrid Columns="4"/>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>

预期结果:

Example result

使用略微修改的UniformGrid(取自this MSDN question)可以实现垂直方向:

public class UniformGridWithOrientation : UniformGrid  
{
    public static readonly DependencyProperty OrientationProperty =  
        DependencyProperty.Register( "Orientation", typeof( System.Windows.Controls.Orientation ), typeof( UniformGridWithOrientation ),  
            new FrameworkPropertyMetadata(   
                System.Windows.Controls.Orientation.Vertical,   
                FrameworkPropertyMetadataOptions.AffectsMeasure ),    
            new ValidateValueCallback( UniformGridWithOrientation.IsValidOrientation ) );  

    internal static bool IsValidOrientation( object o )  
    {  
        System.Windows.Controls.Orientation orientation = (System.Windows.Controls.Orientation)o;  
        if( orientation != System.Windows.Controls.Orientation.Horizontal )  
        {  
            return ( orientation == System.Windows.Controls.Orientation.Vertical );  
        }  
        return true;  
    }  

    public System.Windows.Controls.Orientation Orientation  
    {  
        get { return (System.Windows.Controls.Orientation)GetValue( OrientationProperty ); }  
        set { SetValue( OrientationProperty, value ); }  
    }

    private int _columns;  
    private int _rows;  

    protected override Size MeasureOverride( Size constraint )  
    {  
        this.UpdateComputedValues();  
        Size availableSize = new Size( constraint.Width / ( (double)this._columns ), constraint.Height / ( (double)this._rows ) );  
        double width = 0.0;  
        double height = 0.0;  
        int num3 = 0;  
        int count = base.InternalChildren.Count;  
        while( num3 < count )  
        {  
            UIElement element = base.InternalChildren[ num3 ];  
            element.Measure( availableSize );  
            Size desiredSize = element.DesiredSize;  
            if( width < desiredSize.Width )  
            {  
                width = desiredSize.Width;  
            }  
            if( height < desiredSize.Height )  
            {  
                height = desiredSize.Height;  
            }  
            num3++;  
        }  
        return new Size( width * this._columns, height * this._rows );  
    }  

    private void UpdateComputedValues()  
    {  
        this._columns = this.Columns;  
        this._rows = this.Rows;  
        if( this.FirstColumn >= this._columns )  
        {  
            this.FirstColumn = 0;  
        }  

        if( FirstColumn > 0 )  
            throw new NotImplementedException( "There is no support for seting the FirstColumn (nor the FirstRow)." );  
        if( ( this._rows == 0 ) || ( this._columns == 0 ) )  
        {  
            int num = 0;    // Visible children  
            int num2 = 0;  
            int count = base.InternalChildren.Count;  
            while( num2 < count )  
            {  
                UIElement element = base.InternalChildren[ num2 ];  
                if( element.Visibility != Visibility.Collapsed )  
                {  
                    num++;  
                }  
                num2++;  
            }  
            if( num == 0 )  
            {  
                num = 1;  
            }  
            if( this._rows == 0 )  
            {  
                if( this._columns > 0 )  
                {  
                    this._rows = ( ( num + this.FirstColumn ) + ( this._columns - 1 ) ) / this._columns;  
                }  
                else 
                {  
                    this._rows = (int)Math.Sqrt( (double)num );  
                    if( ( this._rows * this._rows ) < num )  
                    {  
                        this._rows++;  
                    }  
                    this._columns = this._rows;  
                }  
            }  
            else if( this._columns == 0 )  
            {  
                this._columns = ( num + ( this._rows - 1 ) ) / this._rows;  
            }  
        }  
    }  

    protected override Size ArrangeOverride( Size arrangeSize )  
    {  
        Rect finalRect = new Rect( 0.0, 0.0, arrangeSize.Width / ( (double)this._columns ), arrangeSize.Height / ( (double)this._rows ) );  
        double height = finalRect.Height;  
        double numX = arrangeSize.Height - 1.0;  
        finalRect.X += finalRect.Width * this.FirstColumn;  
        foreach( UIElement element in base.InternalChildren )  
        {  
            element.Arrange( finalRect );  
            if( element.Visibility != Visibility.Collapsed )  
            {  
                finalRect.Y += height;  
                if( finalRect.Y >= numX )  
                {  
                    finalRect.X += finalRect.Width;  
                    finalRect.Y = 0.0;  
                }  
            }  
        }  
        return arrangeSize;  
    }  
}  

设置Orientation="Vertical"时的结果:

enter image description here