65.9K
CodeProject 正在变化。 阅读更多。
Home

带有预览的高级 CtrlTab MDI 窗体

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.25/5 (4投票s)

2007年2月27日

CPOL

1分钟阅读

viewsIcon

54803

downloadIcon

1520

MDI 表单中带有预览的高级 CtrlTab。

Screenshot - AdvancedCtrlTabDemo.jpg

引言

几周前,我从 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:基本操作…
© . All rights reserved.