詳解使用C#製作不規則表單的方法

來源:互聯網
上載者:User

本文轉自翔宇網http://www.biye5u.com/article/Csharp/winform/2010/2593.html

以前想製作不規則表單,大多使用API函數來實現,在C#中,也可以不使用API函數照樣能製作出漂亮的不規則表單,下面就介紹一下相關方法。

1、首先準備一張BMP格式的圖片

圖片的形式隨意,但注意圖片的背景最好設定成C#中提供的一些色系,如白色(#FFFFFF\white)、黑色(#000000\black)、黃色(#FFFF00\yellow)、藍色(#0000FF\blue)、紅色(#FF0000\red)或綠色(#00FF00\green)等。本文使用如下形式的圖片,其背景為白色。

2、建立Windows程式

開啟Visual studio 2005,當然,這裡使用的是VS2005,具體是什麼版本無所謂關鍵是方法。建立一個windows應用程式,項目起名為abnormalwin,如所示:

 

設定完成後單擊【確定】,系統自動建立好一個預設的介面,並自動命名為form1。

3、設定相關屬性

(1)將 FormBorderStyle 屬性設定為 None;

(2)將表單的 BackgroundImage 屬性設定為前面準備好的BMP圖片;

(3)將 TransparencyKey 屬性設定為位元影像檔案的背景色,本例中為白色。

如果你的電腦顏色設定低於24位,現在就可以產生相應的效果了,但是如果你的電腦顏色高於24位,就不會產生任何效果,這怎麼辦呢?有人想辦法用以下方式解決了這個問題。

4、定義一個圖片處理類BitmapRegion

這個類是有熱心網友翻譯國外的文章而來的。具體定義方法如下:

(1)在解決方案項目abnormalwin上右擊後,選擇【添加】—>【類】,如所示操作:

 

(2)在彈出的添加新項表單中,輸入類的名稱BitmapRegion.cs,然後單擊【添加】。

(3)輸入下面的代碼

將類檔案中自動產生的程式碼用如下代碼代替之:

View Code

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using System.Text;

namespace abnormalwin
{
public class BitmapRegion
{
public BitmapRegion()
{ }
///<summary>
///Create and apply the region on the supplied control
///建立支援位元影像地區的控制項(目前有button和form)
///</summary>
///<param name="control">The Control object to apply the region to控制項</param>
///<param name="bitmap">The Bitmap object to create the region from位元影像</param>
public static void CreateControlRegion(Control control, Bitmap bitmap)
{
// Return if control and bitmap are null
//判斷是否存在控制項和位元影像
if (control == null || bitmap == null)
return;
// Set our control''s size to be the same as the bitmap
//設定控制項大小為位元影像大小
control.Width = bitmap.Width;
control.Height = bitmap.Height;

// Check if we are dealing with Form here
//當控制項是form時
if (control is System.Windows.Forms.Form)
{
// Cast to a Form object
//強制轉換為FORM
Form form = (Form)control;
// Set our form''s size to be a little larger that the bitmap just
// in case the form''s border style is not set to none in the first place
//當FORM的邊界FormBorderStyle不為NONE時,應將FORM的大小設定成比位元影像大小稍大一點
form.Width = control.Width;
form.Height = control.Height;
// No border
//沒有邊界
form.FormBorderStyle = FormBorderStyle.None;
// Set bitmap as the background image
//將位元影像設定成表單背景圖片 http://www.mscto.com
form.BackgroundImage = bitmap;
// Calculate the graphics path based on the bitmap supplied
//計算位元影像中不透明部分的邊界
GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
// Apply new region
//應用新的地區
form.Region = new Region(graphicsPath);
}
// Check if we are dealing with Button here
//當控制項是button時
else if (control is System.Windows.Forms.Button)
{
// Cast to a button object
//強制轉換為 button
Button button = (Button)control;
// Do not show button text
//不顯示button text
button.Text = "";
// Change cursor to hand when over button
//改變 cursor的style
button.Cursor = Cursors.Hand;
// Set background image of button
//設定button的背景圖片
button.BackgroundImage = bitmap;
// Calculate the graphics path based on the bitmap supplied
//計算位元影像中不透明部分的邊界
GraphicsPath graphicsPath = CalculateControlGraphicsPath(bitmap);
// Apply new region
//應用新的地區
button.Region = new Region(graphicsPath);
}
}
///<summary>
/// Calculate the graphics path that representing the figure in the bitmap
/// excluding the transparent color which is the top left pixel.
/// 計算位元影像中不透明部分的邊界
///</summary>
///<param name="bitmap">The Bitmap object to calculate our graphics path from</param>
///<returns>Calculated graphics path</returns>
private static GraphicsPath CalculateControlGraphicsPath(Bitmap bitmap)
{
// Create GraphicsPath for our bitmap calculation
//建立 GraphicsPath
GraphicsPath graphicsPath = new GraphicsPath();
// Use the top left pixel as our transparent color
//使用左上方的一點的顏色作為我們透明色
Color colorTransparent = bitmap.GetPixel(0, 0);
// This is to store the column value where an opaque pixel is first found.
// This value will determine where we start scanning for trailing opaque pixels.
//第一個找到點的X
int colOpaquePixel = 0;
// Go through all rows (Y axis)
// 偏曆所有行(Y方向)
for (int row = 0; row < bitmap.Height; row++)
{
// Reset value
//重設
colOpaquePixel = 0;
// Go through all columns (X axis)
//偏曆所有列(X方向)
for (int col = 0; col < bitmap.Width; col++)
{
// If this is an opaque pixel, mark it and search for anymore trailing behind
//如果是不需要透明處理的點則標記,然後繼續偏曆
if (bitmap.GetPixel(col, row) != colorTransparent)
{
// Opaque pixel found, mark current position
//記錄當前
colOpaquePixel = col;
// Create another variable to set the current pixel position
//建立新變數來記錄當前點
int colNext = col;
// Starting from current found opaque pixel, search for anymore opaque pixels
// trailing behind, until a transparent pixel is found or minimum width is reached
//從找到的不透明點開始,繼續尋找不透明點,一直到找到或則達到圖片寬度
for (colNext = colOpaquePixel; colNext < bitmap.Width; colNext++)
if (bitmap.GetPixel(colNext, row) == colorTransparent)
break;
// Form a rectangle for line of opaque pixels found and add it to our graphics path
//將不透明點加到graphics path
graphicsPath.AddRectangle(new Rectangle(colOpaquePixel, row, colNext - colOpaquePixel, 1));
// No need to scan the line of opaque pixels just found
col = colNext;
}
}
}
// Return calculated graphics path
return graphicsPath;
}
}
}

5、為表單的Load事件編寫程式

雙擊表單,程式預設是為表單的Load事件添加處理常式,然後在游標處書寫下面的代碼:

BitmapRegion BitmapRegion = new BitmapRegion();//此為產生不規則表單和控制項的類BitmapRegion.CreateControlRegion(this, new Bitmap("xyt.bmp"));

6、使表單能夠最大化、最小化和關閉

在程式相應位置添加三個按鈕控制項,主要是為了實現最大化、最小化和關閉功能,並且將三個按鈕的文本分別設定為“口,—,X”,或者自己使用比較漂亮的圖片按鈕會更好,如果你借用按鈕的滑鼠滑過、按下、放下等事件實現更進階的效果那會更炫。

(1)雙擊最大化按鈕,程式自動添加按鈕的單擊事件處理常式,編寫代碼如下:

if (this.WindowState == FormWindowState.Maximized)//如果已經最大化     this.WindowState = FormWindowState.Normal;//視窗正常大小             else       this.WindowState = FormWindowState.Maximized; //視窗最大化

(2)用同樣的方法為最小化按鈕添加如下程式碼:

this.WindowState = FormWindowState.Minimized;//視窗最小化

(3)用同樣的方法為關閉按鈕添加如下程式碼:

this.Close();

7、實現表單的拖拽功能

首先為該表單添加兩個成員變數:雙擊表單介面,找到如下代碼:

        public Form1()         {             InitializeComponent();         }

在該代碼前添加如下兩個變數成員:

        private Point mouseOffset;        //記錄滑鼠指標的座標  

       private bool isMouseDown = false; //記錄滑鼠按鍵是否按下

回到設計介面,在右側屬性視窗中找到事件表徵圖(類似閃電的表徵圖),單擊該按鈕,轉換到表單的事件介面,接下來為其添加相關事件處理常式。

(1)找到MouseDown事件,雙擊該事件,在游標處添加如下代碼:

        private void Form1_MouseDown(object sender, MouseEventArgs e)        {            int xOffset;            int yOffset;            if (e.Button == MouseButtons.Left)            {                xOffset = -e.X - SystemInformation.FrameBorderSize.Width;                yOffset = -e.Y - SystemInformation.CaptionHeight - SystemInformation.FrameBorderSize.Height;                mouseOffset = new Point(xOffset, yOffset);                isMouseDown = true;            }        }

(2)找到MouseMove事件,雙擊該事件後,為其添加如下代碼:

        private void Form1_MouseMove(object sender, MouseEventArgs e)        {            if (isMouseDown)            {                Point mousePos = Control.MousePosition;                mousePos.Offset(mouseOffset.X, mouseOffset.Y);                Location = mousePos;            }        }

(3)找到MouseUp事件,雙擊該事件後為其添加如下代碼:

        private void Form1_MouseUp(object sender, MouseEventArgs e)        {            // 修改滑鼠狀態isMouseDown的值            // 確保只有滑鼠左鍵按下並移動時,才移動表單            if (e.Button == MouseButtons.Left)            {                isMouseDown = false;            }        }

8、程式運行效果

按下F5鍵就可以看一下程式的運行效果了,本例的運行效果如下所示:

9、本方法的優劣勢

使用此方法製作的不規則表單,相對API來說編寫的代碼較少,對於複雜的不規則表單來說較好,但是執行效率較低,應為程式運行起來後,他調用BitmapRegion類的相關方法把你設定的底色一點點的去掉,因此速度相對較慢,如果機器運行較慢的話,會看到這個過程。

本例原始碼下載:點擊下載此檔案

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.