首页 > 其他分享 >WinForm 简单实现仿WPF的WrapPanel和StackPanel

WinForm 简单实现仿WPF的WrapPanel和StackPanel

时间:2024-10-24 15:34:47浏览次数:1  
标签:StackPanel Height Width int curLineMaxHeight curLineWidth WPF childCtrl WinForm

public interface IDesiredPanel
{
    Size GetDesiredSize(int availableWidth, int avaiableHeight);
}


public class StackPanel : Panel, IDesiredPanel
{


    protected override void OnLayout(LayoutEventArgs levent)
    {
        base.OnLayout(levent);

        List<Control> visibleCtrls = GetVisiableControls();

        int renderHeight = 0;
        for (int i = 0; i < visibleCtrls.Count; i++)
        {
            Control childCtrl = visibleCtrls[i];
            IDesiredPanel idesiredPnl = childCtrl as IDesiredPanel;
            Size childDesignSize = idesiredPnl == null
                   ? new Size(childCtrl.Width, childCtrl.Height)
                   : idesiredPnl.GetDesiredSize(this.Width, this.Height);

            childCtrl.Location = new Point(0, renderHeight);
            childCtrl.Width = childDesignSize.Width;
            renderHeight += childDesignSize.Height;
        }

        if (this.Parent is IDesiredPanel)
        {
            if (visibleCtrls.Count > 0)
            {
                this.Height = renderHeight;
            }
            else
            {
                this.Height = 3;
            }
        }
        else if (this.DesignMode == false)
        {
            this.Height = renderHeight;
        }
    }

    private List<Control> GetVisiableControls()
    {
        List<Control> controls = new List<Control>();
        foreach (Control c in this.Controls)
        {
            if (c.Visible)
            {
                controls.Add(c);
            }
        }
        controls.Reverse();
        return controls;
    }
    public Size GetDesiredSize(int availableWidth, int avaiableHeight)
    {
        List<Control> visibleCtrls = GetVisiableControls();
        int desiredHeight = 0;
        for (int i = 0; i < visibleCtrls.Count; i++)
        {
            Control childCtrl = visibleCtrls[i];
            IDesiredPanel idesiredPnl = childCtrl as IDesiredPanel;
            Size childDesiredSize = idesiredPnl == null
                   ? new Size(childCtrl.Width, childCtrl.Height)
                   : idesiredPnl.GetDesiredSize(availableWidth, avaiableHeight);

            desiredHeight += childDesiredSize.Height;
        }
        return new Size(availableWidth, desiredHeight);
    }

}

public class WrapPanel : Panel, IDesiredPanel
{
    protected override void OnLayout(LayoutEventArgs levent)
    {
        base.OnLayout(levent);

        List<Control> visibleCtrls = GetVisiableControls();


        int renderHeight = 0;
        int curLineWidth = 0, curLineMaxHeight = 0;
        for (int i = 0; i < visibleCtrls.Count; i++)
        {
            Control childCtrl = visibleCtrls[i];
            IDesiredPanel idesiredPnl = childCtrl as IDesiredPanel;
            Size childDesignSize = idesiredPnl == null
                   ? new Size(childCtrl.Width, childCtrl.Height)
                   : idesiredPnl.GetDesiredSize(this.Width, this.Height);

            childCtrl.Width = childDesignSize.Width;
            childCtrl.Height = childDesignSize.Height;
            if (curLineWidth == 0)
            {   //第一个元素
                curLineMaxHeight = Math.Max(curLineMaxHeight, childDesignSize.Height);
                childCtrl.Location = new Point(0, renderHeight);
                curLineWidth += childDesignSize.Width;                   
            }
            else if (curLineWidth + childDesignSize.Width < this.Width)
            {   //非第一个元素,再次元素则宽度累加 不会超出
                childCtrl.Location = new Point(curLineWidth, renderHeight);
                curLineWidth += childDesignSize.Width;
            }
            else
            {   //非第一个元素,再次元素则宽度累加 会超出,采用换行
                renderHeight += curLineMaxHeight;

                //换行了
                childCtrl.Location = new Point(0, renderHeight);
                curLineWidth = childCtrl.Width;
                curLineMaxHeight = childCtrl.Height;
            }


            if (curLineWidth > this.Width)
            {   //这个元素溢出了
                renderHeight += curLineMaxHeight;       //累加上
                curLineWidth = 0;       //重置为0
                curLineMaxHeight = 0;   //需要换到下一行
            }
        }
        if (curLineWidth > 0)
        {
            renderHeight += curLineMaxHeight;
        }

        if(this.Parent is IDesiredPanel)
        {
            if(visibleCtrls.Count>0)
            {
                this.Height =  renderHeight;
            }
            else
            {
                this.Height = 3;
            }
        }
        else if (this.DesignMode == false)
        {
            this.Height = renderHeight;
        }
    }
    private List<Control> GetVisiableControls()
    {
        List<Control> controls = new List<Control>();
        foreach (Control c in this.Controls)
        {
            if (c.Visible)
            {
                controls.Add(c);
            }
        }
        controls.Reverse();
        return controls;
    }

    public Size GetDesiredSize(int availableWidth,int avaiableHeight)
    {
        List<Control> visibleCtrls = GetVisiableControls();
        int desiredHeight = 0;
        int curLineWidth = 0,curLineMaxHeight = 0;
        for (int i = 0; i < visibleCtrls.Count; i++)
        {
            Control childCtrl = visibleCtrls[i];
            IDesiredPanel idesiredPnl = childCtrl as IDesiredPanel;
            Size childDesiredSize = idesiredPnl == null
                   ? new Size(childCtrl.Width, childCtrl.Height)
                   : idesiredPnl.GetDesiredSize(availableWidth,avaiableHeight);

            if (curLineWidth == 0)
            {
                curLineMaxHeight = Math.Max(curLineMaxHeight, childDesiredSize.Height);
                curLineWidth += childDesiredSize.Width;
            }
            else if (curLineWidth + childDesiredSize.Width < availableWidth)
            {
                curLineWidth += childDesiredSize.Width;
            }
            else
            {
                desiredHeight += curLineMaxHeight;

                curLineWidth = childCtrl.Width;
                curLineMaxHeight = childCtrl.Height;
            }
            if (curLineWidth > availableWidth)
            {
                desiredHeight += curLineMaxHeight;
                curLineWidth = 0;
                curLineMaxHeight = 0;
            }
        }
        if (curLineWidth > 0)
        {
            desiredHeight += curLineMaxHeight;
        }
        return new Size(availableWidth, desiredHeight);
    }
}

标签:StackPanel,Height,Width,int,curLineMaxHeight,curLineWidth,WPF,childCtrl,WinForm
From: https://www.cnblogs.com/wandia/p/18499674

相关文章

  • DevExpress WinForms中文教程:Data Grid - 如何在代码中处理列?
    在本教程中,您将学习如何在分配数据源时启用或禁用自动列生成,如何手动填充列集合和访问单个列。请注意,本教程的重点是在代码中完成这些任务。显然您也可以使用网格的集成设计器对话框和VisualStudio的属性网格来做同样的事情,这将在单独的教程中进行描述。P.S:DevExpressWinForms......
  • wpf移除事件委托
    publicclassEventHandlerHelper{publicstaticDelegateGetEventDelegate(RoutedEventHandlerInfo[]rehis,stringmethod_name){foreach(RoutedEventHandlerInforhinrehis){if(rh.Handler.Meth......
  • C#中WPF和WinForms有什么区别?
    C#中WPF和WinForms有什么区别? WPF(WindowsPresentationFoundation)和WinForms(WindowsForms)都是微软提供的用于开发Windows桌面应用程序的框架,但它们在设计理念、功能和用户体验方面存在一些显著的差异:用户界面的构建方式:WPF 使用XAML(eXtensibleApplicationMarkupLang......
  • C#WPF基本概念
    一、什么是WPF?C#WPF,即WindowsPresentationFoundation,是一个用于构建Windows桌面应用程序的UI框架。WPF支持广泛的应用程序开发功能,包括应用模型、资源、控件、图形、布局、数据绑定、文档和安全性。它是.NETFramework的一部分,允许开发者使用C#等.NET语言来创建应用程序。W......
  • WPF - 集成HandyControl UI组件库
    WPF-集成HandyControlUI组件库 环境:net6+wpf+ HandyControl  一.创建项目   二.安装  NuGet包dotnetaddpackageHandyControl  三. 引入HandyControl资源字典 在你的WPF项目中的 App.xaml 或主题文件中1.引入HandyControl资源字典......
  • DevExpress WPF中文教程:Data Grid的视图概述及主要功能一览
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为中心......
  • DevExpress WPF中文教程:Data Grid的视图概述及主要功能一览
    DevExpressWPF拥有120+个控件和库,将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpressWPF能创建有着强大互动功能的XAML基础应用程序,这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。无论是Office办公软件的衍伸产品,还是以数据为......
  • 【转】[WPF] 关闭模式决定了应用程序何时关闭
    在WPF(WindowsPresentationFoundation)中,关闭模式(ShutdownMode)决定了应用程序何时关闭。可以通过以下方式设置关闭模式:XAML设置:在 App.xaml 文件中,可以通过 ShutdownMode 属性来设置关闭模式。WPF提供了三种关闭模式:OnLastWindowClose:默认值,当最后一个窗口关闭时,......
  • WPF中Grid、StackPanel、Canvas、WrapPanel常用属性
    Grid常用属性Grid控件在WPF中非常强大,它提供了多种属性来定义行和列的布局。以下是一些常用的Grid属性:RowDefinitions和ColumnDefinitions:Grid 控件使用 RowDefinitions 和 ColumnDefinitions 来定义行和列的集合。每个 RowDefinition 和 ColumnDefinition......
  • c# winform在线升级clickonce
     说明:在线升级前提1,一个可以访问在线的地址,2,发布前要在项目属性发布里配置好相关设置一,可以在IIS上布署一个可以访问的地址 二,发布前配置  应用程序文件项目下的相关文件右键属性,生成操作选择内容才会在发布后都生成出来。  系统必备组件 选择你的程序......