ListBox ItemsPanel样式

时间:2015-06-11 19:40:48

标签: c# wpf listbox

我试图对我的ListBox进行样式化,我希望我的项目能够像这样:

1 4 7 10 13 16 19 22 25 28

2 5 8 11 14 17 20 23 26 29

3 6 9 12 15 18 21 24 27 30

垂直只有3个项目,ScrollBar是水平的。

我尝试了什么:

<Setter Property="ItemsPanel">
            <Setter.Value>
                <ItemsPanelTemplate>
                    <WrapPanel Orientation="Horizontal" />
                </ItemsPanelTemplate>
            </Setter.Value>
        </Setter>

但是没有用,我不知道该怎么做

2 个答案:

答案 0 :(得分:1)

这似乎是解决方案:

public class UniformGridWithOrientation : UniformGrid
{
    #region Orientation (Dependency Property)
    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); }
    }
    #endregion

    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 int _columns;
    private int _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;
    }
}

将此类放在您的一个名称空间中。

这是我的XAML:

<Window x:Class="ListItemsVerticaly3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:ListItemsVerticaly3"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ListView ItemsSource="{Binding numbers}">
        <ListView.ItemsPanel>
            <ItemsPanelTemplate>
                <local:UniformGridWithOrientation Rows="3" />
            </ItemsPanelTemplate>
        </ListView.ItemsPanel>
    </ListView>
</Grid>

这是我得到的结果:

enter image description here

忘记了我的代码,简单但它完成了这个例子的工作:

public partial class MainWindow : Window
{
    public ObservableCollection<int> numbers { get; set; }
    public MainWindow()
    {
        InitializeComponent();
        numbers = new ObservableCollection<int>();

        IEnumerable<int> generatedNumbers = Enumerable.Range(1, 20).Select(x => x);

        foreach (int nr in generatedNumbers)
        {
            numbers.Add(nr);
        }
        this.DataContext = this;
    }
}

答案 1 :(得分:0)

试试这个解决方案:

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"></StackPanel>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>

使用ListView我们也可以实现

 <ListView.ItemsPanel>
      <ItemsPanelTemplate>
         <WrapPanel Width="{Binding (FrameworkElement.ActualWidth), 
            RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}"
            ItemWidth="{Binding (ListView.View).ItemWidth, 
            RelativeSource={RelativeSource AncestorType=ListView}}"
            MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}"
            ItemHeight="{Binding (ListView.View).ItemHeight, 
            RelativeSource={RelativeSource AncestorType=ListView}}" />
      </ItemsPanelTemplate>
   </ListView.ItemsPanel>