C# 用tabcontrol实现窗体类似网页排版的显示
这里做的比较简陋,可以美化下
把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);
}
}
}
}
C# 用tabcontrol实现窗体类似网页排版的显示的更多相关文章
- 学习笔记 第十二章 CSS3+HTML5网页排版
第12章 CSS3+HTML5网页排版 [学习重点] 正确使用HTML5结构标签 正确使用HTML5语义元素 能够设计符合标准的网页结构 12.1 使用结构标签 在制作网页时,不仅需要使用< ...
- CSS网页排版
自印刷出版物诞生以来,排版就一直是平面设计的基础. 同样,排版在网页设计中也扮演着重要角色. 1.CSS的基本排版技术 1.1 文本颜色 对应网页而言,文本颜色也许是最基本的样式之一. 默认情况下,浏 ...
- Js打开网页后居中显示
使用JavaScript定义打开网页后居中显示,并可为窗口设置大小,使用“window.open”方法打开新窗口:先来看完整的代码及调用方法: <html xmlns="http:// ...
- WinForm实现类似QQ停靠,显示隐藏过程添加特效效果
原文:WinForm实现类似QQ停靠,显示隐藏过程添加特效效果 这可能是个老题长谈的问题了,只是在项目中会用到这个效果,所以今天做个记录.大家见了别喷我.在项目中的需求是这样的. 打开程序,在屏幕的右 ...
- C#基础系列:开发自己的窗体设计器(PropertyGrid显示中文属性名)
既然是一个窗体设计器,那就应该能够设置控件的属性,设置属性最好的当然是PropertyGrid了,我们仅仅需要使用一个PropertyGrid.SelectedObject = Control就可以搞 ...
- (转载)调用ob_end_flush()网页仍旧不能显示有关问题
(转载)http://www.myexception.cn/php/558638.html 调用ob_end_flush()网页仍旧不能显示问题?写了一个简单的demo,理论上调用ob_end_flu ...
- javascript DOM(2) 一个网页上切换显示不同的图片或文本
摘自: javascript DOM 编程艺术 1. 在一个网页上切换显示不同的图片 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tran ...
- 网页title左边显示网页的logo图标
打开某一个网页会在浏览器的标签栏处显示该网页的标题和图标,当网页被添加到收藏夹或者书签中时也会出现网页的图标,怎么在网页title左边显示网页的logo图标呢? 方法1: 找一个或者作一个ico文件, ...
- ifram的使用 左边是<a>链接 右边是对应网页嵌套的显示网页链接内容 和toggle的收放用法
1.ifram的使用 左边是<a>链接 右边是对应网页嵌套的显示网页链接内容 <div class="container"> <div class= ...
随机推荐
- 【SSO单点系列】(6):CAS4.0 单点流程序列图(中文版)以及相关术语解释(TGT、ST、PGT、PT、PGTIOU)
CAS 相关的内容好久没写了,可能下周会继续更新一些内容吧. 在上一篇中的单点流程序列图由于是从官网直接下载来的,上面都是英文,可能有的朋友看不懂,因此修改成中文的. PS:只修改了一个,第二个图明天 ...
- 5. 常见C语言字符串库函数的使用及实现
1. strncat 函数: [函数原型]#include <string.h> char *strncat( char *str1, const char *str2, size_t c ...
- python之IO目录处理
IO目录处理 在使用io常用函数之前,必须要在py文件头部import os.os是(Operation system)的缩写,意思就是系统操作. 1. 创建删除目录 #!/usr/bin/pytho ...
- POJ_3696 The Luckiest number 【欧拉定理+同余式+对取模的理解】
一.题目 Chinese people think of '8' as the lucky digit. Bob also likes digit '8'. Moreover, Bob has his ...
- CF D - Beautiful Graph(dfs 染色问题吧)给你一个图,每个节点可以赋值1,2,3三种数字,相邻的节点的和必须是奇数,问有多少中方法。
题意: 给你一个图,每个节点可以赋值1,2,3三种数字,相邻的节点的和必须是奇数,问有多少中方法. 分析: 很容易就可以发现如果这个图中是有奇数的环的话,那这是肯定不行的 ,否则这个环的贡献是为2^s ...
- 112th LeetCode Weekly Contest Validate Stack Sequences
Given two sequences pushed and popped with distinct values, return true if and only if this could ha ...
- POJ - 1011 剪枝练习
题意:给定n条拆掉的棍子,问能凑成最短的多条相同长度棍子的最短长度 x:当前第几条正在合成的棍子 y:目前正在尝试的拆掉的棍子 z:当前长度 剪枝方案: 1.按照长度单调性排序,减少重复搜索 2.如果 ...
- 方格填数--蓝桥杯---dfs
答案:1580 相似题目:N皇后问题 注意要枚举的是什么 #include<iostream> #include<string.h> using namespace std; ...
- win10更新后电脑没声音问题
2018-07-18 问题描述: win10系统更新之后,发现电脑突然没声音了 解决方案: 找到了一个软件,测试超级好用,下载链接 链接:https://pan.baidu.com/s/1iKTHp7 ...
- 红米note_维修_开机键
1. 2.在线人工客服(20180919) 很荣幸为您服务,有什么问题可以帮助到您的- 我的手机 后边的 开机键 貌似 不太行了 您好,您是哪款手机 就是 要按 好几次 很用力 才能 开亮手机屏幕木 ...