简体   繁体   中英

How to display items based on the height in ListBox in WPF?

I am binding around 100 items to ListBox. The items are displaying as vertically like below:

<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>

垂直排列的物品

But I want it show in horizontally. After searching on google I tried the below code:

<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>

Now it is displaying like this. But I want to show 4 rows in a column. Can any one help me with this?

水平排列的物品

Thanks in advance.

Sounds like a perfect use case for a UniformGrid :

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

Expected result:

结果示例

Vertical Orientation can be achieved with a slightly modified UniformGrid (taken from 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;  
    }  
}  

Result when you set Orientation="Vertical" :

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM