C# 用tabcontrol实现窗体类似网页排版的显示
阅读原文时间:2023年07月14日阅读:2

这里做的比较简陋,可以美化下

把form设置为非顶级控件,直接放在tabcontrol里边,然后实现tabcontrol的拖拽移除tabpage显示form以及添加tabpage

mousemove的触发时机需要优化一下

这里是比较简单的实现方式,也比较丑,可以实现像QQ那样的效果,可以重绘tabcontrol控件,然后以同样的方式实现拖拽移除显示和添加tabpage

也可以实现类似timQQ那样的形式,可以用自定义控件左边用listview右边放容器,重绘listview控件然后实现拖拽显示和添加,这样做复杂一点,但是会好看很多····

public Form1()
{
InitializeComponent();
}
private TabControl tabControl1 = new TabControl();
private bool StartMove = false;
private bool flag = true;
private TabPage MovePage = null;
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
tabControl1.Dock = DockStyle.Fill;

        this.Controls.Add(tabControl1);  
        this.Controls.SetChildIndex(tabControl1, );  
        frm1ToolStripMenuItem.Click += delegate {  
            var frm1 = new Form();  
            frm1.Text = "frm1";  
            var btn=new Button();  
            btn.Text = "btn";  
            btn.Click += delegate { MessageBox.Show("this is frm1"); btn.Text = "frm1"; };  
            frm1.Controls.Add(btn);  
            addfrm(frm1);  
        };  
        frm2ToolStripMenuItem.Click += delegate  
        {  
            var frm1 = new Form();  
            frm1.Text = "frm2";  
            var btn = new Button();  
            btn.Text = "btn";  
            btn.Click += delegate { MessageBox.Show("this is frm2"); };  
            frm1.Controls.Add(btn);  
            addfrm(frm1);  
        };  
        frm3ToolStripMenuItem.Click += delegate  
        {  
            var frm1 = new Form();  
            frm1.Text = "frm3";  
            var btn = new Button();  
            btn.Text = "btn";  
            btn.Click += delegate { MessageBox.Show("this is frm3"); };  
            frm1.Controls.Add(btn);  
            addfrm(frm1);  
        };  
        tabControl1.AllowDrop = true;  
        Func<Point, TabPage> GetTabPageByTab = (point) =>  
        {  
            for (int i = ; i < this.tabControl1.TabPages.Count; i++)  
            {  
                if (tabControl1.GetTabRect(i).Contains(point))  
                {  
                    return this.tabControl1.TabPages\[i\];  
                }  
            }  
            return null;  
        };  
        tabControl1.MouseDown += (o, eg) => {  
            if (flag)  
            {  
                StartMove = true;  
                MovePage=GetTabPageByTab(new Point(eg.X, eg.Y));  
            }  
            flag = true;  
        };  
        tabControl1.MouseUp += (o, eg) => {  
            StartMove = false;  
        };  
        tabControl1.SelectedIndexChanged += (o, eg) => {  
            flag = false;//切换的时候因为失去焦点的原因,会触发down事件不触发up事件这里做屏蔽  
        };  
        tabControl1.MouseMove += (o, eg) => {  
            if (StartMove && flag)  
            {  
                if (MovePage != null)  
                {  
                    this.DoDragDrop(MovePage, DragDropEffects.None);  
                }  
            }  
        };  
        tabControl1.ControlAdded += delegate {  
            StartMove = false;  
            flag = false;  
        };  
        tabControl1.DragOver += (o, eg) => {  
            eg.Effect = DragDropEffects.None;  
            if (tabControl1.TabPages.Count < ) return;  
            TabPage page = (TabPage)eg.Data.GetData(typeof(TabPage));  
            var frm1 = page.Controls\[\] as Form;  
            frm1.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Sizable;  
            frm1.Parent = null;  
            frm1.TopLevel = true;  
            frm1.Owner = this;  
            frm1.Location = new Point(eg.X, eg.Y);  
            frm1.Show();  
            tabControl1.TabPages.Remove(page);  
            MovePage = null;  
            frm1.Move += (oo, ee) =>  
            {  
                for (int i = ; i < tabControl1.TabPages.Count; i++)  
                {  
                    if (tabControl1.GetTabRect(i).Contains(this.PointToClient(frm1.Location)))  
                    {  
                        addfrm(frm1);  
                    }  
                }  
            };

        };

    }  
    private void addfrm(Form frm)  
    {  
        if (tabControl1.Visible == false) tabControl1.Visible = true;  
        bool flag = true;  
        frm.TopLevel = false;  
        frm.Dock = DockStyle.Fill;  
        frm.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;  
        frm.Owner = null;  
        foreach (TabPage page in tabControl1.TabPages)  
        {  
            if (page.Controls.Count < )  
            {  
                page.Controls.Add(frm);  
                page.Text=frm.Text;  
                flag = false;  
                frm.Show();  
                return;  
            }  
        }  
        if (flag)  
        {  
            var page=new TabPage(frm.Text);  
            page.Controls.Add(frm);  
            tabControl1.TabPages.Add(page);  
            frm.Show();  
        }

    }

之前闲的没事写的tabcontrol加载窗体,刚好最近要用到这个· 这里简单重绘一个·因为要该背景色 去边框之类的,网上查了很多·不太好使·  这里用简单粗暴的方式直接吧背景色刷成想要的 然后在填充其他要改变背景色的地方

using System.Windows.Forms;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ExerciseUIPrj.controls
{
public partial class XTabControl : TabControl
{
Size defaultSize = new Size();
const int dheight = ;
public XTabControl()
{
InitializeComponent();
base.SetStyle(
ControlStyles.UserPaint | // 控件将自行绘制,而不是通过操作系统来绘制
ControlStyles.OptimizedDoubleBuffer | // 该控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁
ControlStyles.AllPaintingInWmPaint | // 控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁
ControlStyles.ResizeRedraw | // 在调整控件大小时重绘控件
ControlStyles.SupportsTransparentBackColor, // 控件接受 alpha 组件小于 255 的 BackColor 以模拟透明
true); // 设置以上值为 true
base.UpdateStyles();
this.SizeMode = TabSizeMode.Fixed; // 大小模式为固定
FontChanged += XTabControl_FontChanged;
defaultSize = TextRenderer.MeasureText("tabpage1", Font);
Margin = new System.Windows.Forms.Padding();
Padding = new Point(, );
Appearance = TabAppearance.Normal;
SetItemSize();
}
//public override Rectangle DisplayRectangle
//{
// get
// {
// Rectangle rect = base.DisplayRectangle;
// return new Rectangle(rect.Left - 2, rect.Top-2, rect.Width + 4, rect.Height + 4);
// }
//}
public void SetItemSize()
{
if (Width >= && TabCount > )
{
if (Alignment ==TabAlignment.Top || Alignment == TabAlignment.Bottom)
{
int width = (int)((Size.Width - ) / (double)this.TabCount);
this.ItemSize = new Size(width, defaultSize.Height + dheight); // 设定每个标签的尺寸
}
else
{
int width = defaultSize.Width;
foreach (TabPage t in TabPages)
{
var w = TextRenderer.MeasureText(t.Name, Font).Width;
width = w > width ? w : width;
}
width = width + dheight;
this.ItemSize = new Size(defaultSize.Height + dheight, width); // 设定每个标签的尺寸 //这里w和h是反的
}

        }  
    }

    private void XTabControl\_FontChanged(object sender, EventArgs e)  
    {  
        defaultSize = TextRenderer.MeasureText("tabpage1", Font);  
        SetItemSize();  
    }  
    Color dbackColor = Color.FromArgb(, , );  
    protected override void OnPaint(PaintEventArgs pe)  
    {  
        var g = pe.Graphics;  
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;  
        g.FillRectangle(new SolidBrush(Color.White), pe.ClipRectangle);//所有背景全刷,直接刷成白色······  
        Rectangle rect = new Rectangle();

        if (Alignment == TabAlignment.Left || Alignment == TabAlignment.Right)  
        {  
            rect = new Rectangle(,, ItemSize.Height+, Height);  
            g.FillRectangle(new SolidBrush(dbackColor), rect);//吧标签背景色统一填充了  
        }  
        else  
        {  
             rect = new Rectangle(, , Width, ItemSize.Height+);  
           // g.FillRectangle(new SolidBrush(dbackColor), rect);  
        }

        for (int i = ; i < this.TabCount; i++)//这里画标签,可以在里边画图片···这里只画文字···  
        {  
            Rectangle bounds = this.GetTabRect(i);  
            if (SelectedIndex == i)  
            {  
                g.FillRectangle(new SolidBrush(Color.White), bounds);  
            }  
            else  
            {  
                g.FillRectangle(new SolidBrush(dbackColor), bounds);  
            }  
            PointF textPoint = new PointF();  
            SizeF textSize = TextRenderer.MeasureText(this.TabPages\[i\].Text, this.Font);  
            textPoint.X= bounds.X + (bounds.Width - textSize.Width) / ;  
            textPoint.Y = bounds.Y + (bounds.Height - textSize.Height) / ;  
            g.DrawString( this.TabPages\[i\].Text,   this.Font, SystemBrushes.ControlText, textPoint.X,  textPoint.Y);  
        }  
    }  
}  

}

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章