带有预览的高级 CtrlTab MDI 窗体






3.25/5 (4投票s)
MDI 表单中带有预览的高级 CtrlTab。
引言
几周前,我从 MSDN Academic Alliance 软件中心下载了 Vista Business,不是从盗版站点下载的 ;-)。在 Vista 中,每个人首先注意到的就是 ALT-TAB “方法”:如果你按住 CTRL 键,你不仅可以看到带有图标的程序列表,还可以看到每个程序的预览。
起初看起来很困难,但实际上并不难!所以我决定在自己的“框架”中实现它。我制作了一个简单的测试应用程序来测试它,当“完成”后,我想把它提交到 CodeProject。
背景
为此,我们只需要开发一个继承的表单,添加事件处理程序,并添加一些代码。
这是表单
namespace KBAdvancedCtrlTab
{
public class KBMDIForm:Form
{
public KBMDIForm()
{
InitializeComponent();
//search the MDIClient Control
foreach (Control act in this.Controls)
{
if (act is MdiClient)
{
//use the MouseWheel event to show the panel with previews
//and scroll between the forms
act.MouseWheel += new MouseEventHandler(MdiClient_MouseWheel);
break;
}
}
//Initialize the 'Feature
InitializeAdvancedCtrlTab(true);
}
private void InitializeComponent()
{
...
this.KeyUp += new System.Windows.Forms.KeyEventHandler
(this.KBMDIForm_KeyUp);
...
}
...
我们需要的控件和变量如下所示
//the selected(focused) picturePox->Form
private int intFocusedPicID =-1;
//the panel size
private Size sizeAdvCtrlTabPanel = new Size(330, 240);
//picture box size
private Size sizeAdvCtrlTabPic = new Size(95, 72);
//picture box count in one row
private int intPreviewPicCountInRow = 3;
//the Preview panel
private Panel pnlAdvancedCtrlTab = new Panel();
//the label that contains the caption of the selected Form
private Label lblSelectedChildCaption = new Label();
以及两个事件处理函数
这是在激活表单时引发的 KeyUp
事件
private void KBMDIForm_KeyUp(object sender, KeyEventArgs e)
{
if (ModifierKeys != Keys.Control)
{
if (intFocusedPicID == -1)
{
return;
}
//if the user release the control key we activate the selected Form
if (this.MdiChildren[intFocusedPicID].WindowState == FormWindowState.Minimized)
{
this.MdiChildren[intFocusedPicID].WindowState = FormWindowState.Normal;
}
this.MdiChildren[intFocusedPicID].Activate();
//remove the panel and the label from MDIForm controls
this.Controls.Remove(pnlAdvancedCtrlTab);
this.Controls.Remove(lblSelectedChildCaption);
intFocusedPicID = -1;
}
}
这是在激活表单时引发的 MouseWheel
事件
private void MdiClient_MouseWheel(object sender, MouseEventArgs e)
{
if (this.MdiChildren.Length > 0)
{
//if there is any ChildForm
if (ModifierKeys == Keys.Control)
{
//control key is down
if (!this.Contains(pnlAdvancedCtrlTab))
{
//if this is the first time, than mouse wheel scroll
//so we need the initialize the panel
//clear all PictureBox
pnlAdvancedCtrlTab.Controls.Clear();
//set the position of the pnl
//it set to be the center of the MDI form
pnlAdvancedCtrlTab.Location
= new Point((int)(this.Width / 2) -
(int)(pnlAdvancedCtrlTab.Width / 2),
(int)(this.Height / 2) -
(int)(pnlAdvancedCtrlTab.Height / 2));
//the position of the label
lblSelectedChildCaption.Location
= new Point(pnlAdvancedCtrlTab.Location.X,
pnlAdvancedCtrlTab.Location.Y - 50);
//style...
pnlAdvancedCtrlTab.BorderStyle = BorderStyle.Fixed3D;
//if the autosroll property is true and we have lot
of opened childwindow,
//the vertical scrollbar automatically appear
pnlAdvancedCtrlTab.AutoScroll = true;
//the x-y "index"
int i = 0;
int j = 0;
foreach (Form act in this.MdiChildren)
{
if (i == intPreviewPicCountInRow)
{
//if we need to change row...
i = 0;
j++;
}
//the new picture box
PictureBox pc = new PictureBox();
//set its size and location
pc.Location = new Point(20+i * (sizeAdvCtrlTabPic.Width + 5),
20+j * (sizeAdvCtrlTabPic.Height + 10));
pc.Size = sizeAdvCtrlTabPic;
//add it to the panel controls collection
pnlAdvancedCtrlTab.Controls.Add(pc);
//set the image and image size
pc.Image = SaveBitmap(act);
pc.SizeMode = PictureBoxSizeMode.Zoom;
i++;
if (act.Focused)
{
//if it is the foucused ChildWindow set its border to 3d
pc.BorderStyle = BorderStyle.Fixed3D;
intFocusedPicID = pnlAdvancedCtrlTab.Controls.Count - 1;
//set the label to the ChildForm caption
lblSelectedChildCaption.Text = act.Text;
}
}
if (intFocusedPicID == -1)
{
//if there isnt any focused child... we set the first selected
intFocusedPicID = 0;
(pnlAdvancedCtrlTab.Controls[0] as PictureBox).BorderStyle =
BorderStyle.Fixed3D;
}
//add the panel and the textbox to to controls collection of the MDIForm
this.Controls.Add(pnlAdvancedCtrlTab);
this.Controls.Add(lblSelectedChildCaption);
}
else
{
//if it isnt the first mouse scroll
//set the actual picBox border to default
(pnlAdvancedCtrlTab.Controls[intFocusedPicID] as
PictureBox).BorderStyle = BorderStyle.None;
//increment,or decrement the selection
if (e.Delta > 0)
{
intFocusedPicID++;
if (intFocusedPicID == pnlAdvancedCtrlTab.Controls.Count)
{
intFocusedPicID = 0;
}
}
else if (e.Delta < 0)
{
intFocusedPicID--;
if (intFocusedPicID == -1)
{
intFocusedPicID = pnlAdvancedCtrlTab.Controls.Count - 1;
}
}
//set the new picBox selected
(pnlAdvancedCtrlTab.Controls[intFocusedPicID]
as PictureBox).BorderStyle = BorderStyle.Fixed3D;
lblSelectedChildCaption.Text = this.MdiChildren[intFocusedPicID].Text;
}
}
}
}
使用代码
你只需要继承你的 MDI 表单 KBAdvancedCtrlTab.KBMDIForm
(或者将代码复制到你自己的表单中)
例如...
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace AdvancedCtrlTabDemo
{
public partial class DemoApp : KBAdvancedCtrlTab.KBMDIForm
{
public DemoApp()
{
InitializeComponent();
newToolStripMenuItem_Click(null, null);
newToolStripMenuItem_Click(null, null);
newToolStripMenuItem_Click(null, null);
}
private int act_im_index = 0;
private void newToolStripMenuItem_Click(object sender, EventArgs e)
{
Form frm = new Form();
frm.MdiParent = this;
frm.BackgroundImage = imageList1.Images[act_im_index];
act_im_index++;
if (act_im_index == 4)
{
act_im_index = 0;
}
frm.Text = "ChildForm - " + this.MdiChildren.Length.ToString();
frm.Show();
}
}
}
最后
当然,这还不是最终版本,可能存在很多问题,而且设计也不够美观……但我认为你可以把它用作一个框架,并根据自己的需要进行定制……我认为更改设计、更改表单切换方式(例如,Ctrl + PageUp、鼠标点击等)、面板大小等都非常容易……
历史
- 1.0:基本操作…