C# 列表框项目面板样式

C# 列表框项目面板样式,c#,wpf,listbox,C#,Wpf,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个项目垂直,滚动条水平 我尝试的是: <Setter Property="ItemsPanel"> <Setter.Value> <Ite

我正在尝试样式化我的
列表框
,我希望我的项目如下所示:

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个项目垂直,滚动条水平

我尝试的是:

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

但是不起作用,我不知道该怎么办

试试这个解决方案:

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"></StackPanel>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>
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;
    }
}

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

这似乎是解决方案:

<ListBox.ItemsPanel>
    <ItemsPanelTemplate>
        <StackPanel Orientation="Horizontal"></StackPanel>
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>
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;
    }
}
公共类UniformGridWithOrientation:UniformGrid
{
#区域方向(依赖项属性)
公共静态只读DependencyProperty方向属性=
DependencyProperty.Register(“方向”)、typeof(System.Windows.Controls.Orientation)、typeof(UniformGridWithOrientation),
新框架属性元数据(
System.Windows.Controls.Orientation.Vertical,
FrameworkPropertyMetadataOptions.AffectsMeasure),
新的ValidateValueCallback(UniformGridWithOrientation.isValidation));
内部静态布尔值有效性(对象o)
{
System.Windows.Controls.Orientation=(System.Windows.Controls.Orientation)o;
if(方向!=System.Windows.Controls.orientation.Horizontal)
{
返回(方向==System.Windows.Controls.orientation.Vertical);
}
返回true;
}
公共系统.Windows.Controls.Orientation
{
获取{return(System.Windows.Controls.Orientation)GetValue(OrientationProperty);}
set{SetValue(方向属性,值);}
}
#端区
受保护的覆盖尺寸测量覆盖(尺寸约束)
{
this.updateComputerdValues();
Size availableSize=新尺寸(constraint.Width/((double)this._列),constraint.Height/((double)this._行));
双倍宽度=0.0;
双倍高度=0.0;
int num3=0;
int count=base.InternalChildren.count;
而(num3<计数)
{
UIElement=base.InternalChildren[num3];
元素。度量(可用性大小);
大小desiredSize=元素。desiredSize;
如果(宽度<所需尺寸宽度)
{
宽度=所需尺寸。宽度;
}
如果(高度<所需尺寸高度)
{
高度=所需尺寸。高度;
}
num3++;
}
返回新大小(宽度*此。\列,高度*此。\行);
}
专用int_列;
私有整数行;
私有void updateComputerdValues()
{
this.\u columns=this.columns;
this._rows=this.rows;
如果(this.FirstColumn>=this.\u columns)
{
this.FirstColumn=0;
}
如果(第一列>0)
抛出新的NotImplementedException(“不支持设置第一列(或第一行)。”;
if((此._行==0)| |(此._列==0))
{
int num=0;//可见子项
int num2=0;
int count=base.InternalChildren.count;
while(num2<计数)
{
UIElement=base.InternalChildren[num2];
if(element.Visibility!=Visibility.Collapsed)
{
num++;
}
num2++;
}
如果(num==0)
{
num=1;
}
如果(此._行==0)
{
如果(此._列>0)
{
this._rows=((num+this.FirstColumn)+(this._columns-1))/this._columns;
}
其他的
{
这个._rows=(int)Math.Sqrt((double)num);
if((此._行*此._行)=numX)
{
finalRect.X+=finalRect.Width;
最终结果Y=0.0;
}
}
}
返回安排大小;
}
}
将该类放在您的一个名称空间中

这是我的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>

这是我得到的结果:

忘记了我的代码,很简单,但它完成了本例的工作:

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;
    }
}
公共部分类主窗口:窗口
{
公共可观测集合数{get;set;}
公共主窗口()
{
初始化组件();
数字=新的ObservableCollection();
IEnumerable generatedNumbers=可枚举。范围(1,20)。选择(x=>x);
foreach(生成的数字中的整数编号)
{
编号。添加(nr);
}
this.DataContext=this;
}
}

它只显示在一行中,如:1 2 3 4 5 6。。。。我想在我试过的第一个“列”上显示3个项目