更改WPF中UniformGrid的布局排列顺序

一.每行显示固定列数

<ListBox ItemsSource="{Binding DataList}" Style="{DynamicResource ListBoxStyle}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
	<ListBox.ItemsPanel>
	    <ItemsPanelTemplate>
	        <UniformGrid Columns="3"/>
	    </ItemsPanelTemplate>
	</ListBox.ItemsPanel>
	<ListBox.ItemTemplate>
	    <DataTemplate>
	        ...
	    </DataTemplate>
	</ListBox.ItemTemplate>
</ListBox>

二.每行显示列数随宽度变化

<ListBox ItemsSource="{Binding DataList}" Style="{DynamicResource ListBoxStyle}" ScrollViewer.HorizontalScrollBarVisibility="Disabled" >
	<ListBox.ItemsPanel>
	    <ItemsPanelTemplate>          
	        <WrapPanel IsItemsHost="True"/>
	    </ItemsPanelTemplate>
	</ListBox.ItemsPanel>
	<ListBox.ItemTemplate>
	    <DataTemplate>
	        ...
	    </DataTemplate>
	</ListBox.ItemTemplate>
</ListBox>

如果想更改他的排列顺序,比如将
1 2 3
4 5 6
7 8 9
改为
7 8 9
4 5 6
1 2 3
参考MSDN

public class HorizontalUniformGrid : UniformGrid
    {
        #region Orientation (Dependency Property)
        public static readonly DependencyProperty OrientationProperty =
            DependencyProperty.Register("Orientation", typeof(System.Windows.Controls.Orientation), typeof(HorizontalUniformGrid),
                new FrameworkPropertyMetadata(
                    System.Windows.Controls.Orientation.Vertical,
                    FrameworkPropertyMetadataOptions.AffectsMeasure),
                new ValidateValueCallback(HorizontalUniformGrid.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 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;
            double yPos = arrangeSize.Height - height;
            finalRect.X += finalRect.Width * this.FirstColumn;

            //TODO
            finalRect.Y += yPos;

            foreach (UIElement element in base.InternalChildren)
            {
                element.Arrange(finalRect);
                if (element.Visibility != Visibility.Collapsed)
                {

                    // Sortierung von unten links nach oben links
                    finalRect.X += finalRect.Width;
                    if (finalRect.X >= arrangeSize.Width)
                    {
                        finalRect.Y -= height;
                        finalRect.X = 0;
                    }
                }
            }
            return arrangeSize;
        }

        private int _columns;
        private int _rows;
    }
    public class VerticalUniformGrid : UniformGrid
    {
        #region Orientation (Dependency Property)  
        public static readonly DependencyProperty OrientationProperty =
            DependencyProperty.Register("Orientation", typeof(System.Windows.Controls.Orientation), typeof(VerticalUniformGrid),
                new FrameworkPropertyMetadata(
                    System.Windows.Controls.Orientation.Vertical,
                    FrameworkPropertyMetadataOptions.AffectsMeasure),
                new ValidateValueCallback(VerticalUniformGrid.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;
            double yPos = arrangeSize.Height - height;
            finalRect.X += finalRect.Width * this.FirstColumn;

            finalRect.Y += yPos;
            foreach (UIElement element in base.InternalChildren)
            {
                element.Arrange(finalRect);
                if (element.Visibility != Visibility.Collapsed)
                {
                    finalRect.Y -= height;
                    if (finalRect.Y < 0)
                    {
                        finalRect.X += finalRect.Width;
                        finalRect.Y = yPos;
                    }
                }
            }
            return arrangeSize;
        }
    }

然后调用,这是从左下到右下的,例如
7 8 9
4 5 6
1 2 3

<ListBox ItemTemplate="{DynamicResource HoleListTemplate}" ItemsSource="{Binding PGHoles}">
     <ListBox.ItemsPanel>
         <ItemsPanelTemplate>
             <local:HorizontalUniformGrid Columns="3" Rows="3"/>
         </ItemsPanelTemplate>
     </ListBox.ItemsPanel>
 </ListBox>

我对他进行了修改,他只有一个从左下到右下的顺序,我增加了一个从左下到左上的顺序,例如
3 6 9
2 5 8
1 4 7

<ListBox ItemTemplate="{DynamicResource HoleListTemplate}" ItemsSource="{Binding PGHoles}">
     <ListBox.ItemsPanel>
         <ItemsPanelTemplate>
             <local:VerticalUniformGrid Columns="3" Rows="3"/>
         </ItemsPanelTemplate>
     </ListBox.ItemsPanel>
 </ListBox>
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
WPF提供了多种控件自动排列布局的方式,以下是其几种常用的方式: 1. WrapPanel WrapPanel是一个自动换行的面板,可以让子元素自动排列,并在需要时自动换行。当子元素宽度超过容器宽度时,WrapPanel会将子元素放到下一行。 示例代码如下: ```xaml <WrapPanel> <Button Content="Button 1" /> <Button Content="Button 2" /> <Button Content="Button 3" /> <Button Content="Button 4" /> <Button Content="Button 5" /> <Button Content="Button 6" /> <Button Content="Button 7" /> <Button Content="Button 8" /> </WrapPanel> ``` 2. UniformGrid UniformGrid是一个均匀排列子元素的面板,可以将子元素均匀分布在多行多列的网格。 示例代码如下: ```xaml <UniformGrid Rows="2" Columns="4"> <Button Content="Button 1" /> <Button Content="Button 2" /> <Button Content="Button 3" /> <Button Content="Button 4" /> <Button Content="Button 5" /> <Button Content="Button 6" /> <Button Content="Button 7" /> <Button Content="Button 8" /> </UniformGrid> ``` 3. DockPanel DockPanel是一个将子元素停靠在容器边缘的面板,可以将子元素停靠在顶部、底部、左侧或右侧。 示例代码如下: ```xaml <DockPanel> <Button Content="Top" DockPanel.Dock="Top" /> <Button Content="Bottom" DockPanel.Dock="Bottom" /> <Button Content="Left" DockPanel.Dock="Left" /> <Button Content="Right" DockPanel.Dock="Right" /> <Button Content="Center" /> </DockPanel> ``` 这些自动排列布局方式都可以方便地实现控件的自动排列布局,具体使用哪种方式取决于您的布局需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值