利用C#實現標註式訊息提示視窗

來源:互聯網
上載者:User
近一段時間由於項目需要一直專註於UI方面的編程,為了更加友好的將提示資訊呈現給使用者,我們必須對標準的Windows訊息提示視窗進行處理。我們大家在Windows XP下使用隨身碟、快閃記憶體等移動存放裝置,當插上或拔下這些裝置時工作列地區都會顯示一個淡黃色背景,且具有標註樣式的提示視窗彈出來,這樣的提示即友善又美觀,那麼這到底是怎麼實現的呢?其實道理並不複雜,該標註式提示視窗本身就是一個不規則表單,當顯示時它會將標註視窗的箭頭指向不同控制項。如:


一般情況下的p標註式提示視窗

螢幕邊緣的標註式提示視窗

  一、技術要點

  就像本文開頭所說的"標註式訊息提示視窗"其實就是一個具有不規則外形的表單,但卻具備了更加複雜的屬性和行為。標註的箭頭會根據不同控制項指向不同的位置,當需要標註的控制項過於接近螢幕的邊緣時,標註視窗還會自動調整顯示位置以及箭頭的長短和大小。

  我們為新建立的表單取名為InfoWindow。在類的頭部定義intArc和intArrowHeight兩個私人變數,可以適當調整它們的值來微調提示視窗的位置和箭頭的大小與位置。

  提示視窗的箭頭位置無非具有左上、右上、左下和右下四個可能性,我們為此定義了枚舉類型的變數ArrowLocation,根據提示視窗位於螢幕的不同位置,GetArrowLocation可以計算提示視窗的位置並且返回適當的ArrowLocation,定義如下:

……
public enum ArrowLocation
{
 TopLeft,
 TopRight,
 BottomLeft,
 BottomRight
}

  SetInfoWindowRegion函數非常重要,它在Form.Load事件即裝載和顯示提示表單時被調用,當計算出新的提示視窗的位置和箭頭顯示位置後,調用SetBounds將更新後的位置和大小應用到提示視窗,gPath是GraphicsPath類型的私人變數,它表示標註式視窗的不規則圖形路徑,該圖行路徑也是根據提示視窗的位置和箭頭顯示的位置來建立,gPath.AddArc方法用來繪製提示視窗四個邊角的弧度部分,和AddLine方法一起描繪出提示視窗包括箭頭的輪廓,一切就緒後我們就用這個gPath對象傳遞給Region對象,當將這個Region對象賦給Form表單的Region屬性後,表單就具備了標註式提示視窗樣式的不規則外形了,部分代碼如下:

private void SetInfoWindowRegion()
{
 if (!this.IsHandleCreated)
  return;
 System.Drawing.Size windowSize = this.Size;
 Point[] ArrowPoints = new Point[3];
 Point topLeftPoint = Point.Empty;
 Point bottomRightPoint = (Point)windowSize;
 switch (this.GetArrowLocation)
 {
  case ArrowLocation.TopLeft:
   ……
  case ArrowLocation.TopRight:
   ……
  case ArrowLocation.BottomLeft:
   ……
  case ArrowLocation.BottomRight:
   ……
 }
 ……
 ……
 if ((this.GetArrowLocation == ArrowLocation.TopLeft) ||
(this.GetArrowLocation == ArrowLocation.TopRight))
 {
  gPath.AddArc(topLeftPoint.X, rectY2 - arcRadius, arcDia, arcDia, 90, 90);
  gPath.AddLine(topLeftPoint.X, rectY2, topLeftPoint.X, rectY1);
  gPath.AddArc(topLeftPoint.X, topLeftPoint.Y, arcDia, arcDia, 180, 90);
  gPath.AddLine(rectX1, topLeftPoint.Y, ArrowPoints[0].X, topLeftPoint.Y);
  gPath.AddLines(ArrowPoints);
  gPath.AddLine(ArrowPoints[2].X, topLeftPoint.Y, rectX2, topLeftPoint.Y);
  gPath.AddArc(rectX2 - arcRadius, topLeftPoint.Y, arcDia, arcDia, 270, 90);
  gPath.AddLine(bottomRightPoint.X, rectY1, bottomRightPoint.X, rectY2);
  gPath.AddArc(rectX2 - arcRadius, rectY2 - arcRadius, arcDia, arcDia, 0, 90);
  gPath.AddLine(rectX2, bottomRightPoint.Y, rectX1, bottomRightPoint.Y);
 }
 else
 {
  gPath.AddLine(rectX1, topLeftPoint.Y, rectX2, topLeftPoint.Y);
  gPath.AddArc(rectX2 - arcRadius, topLeftPoint.Y, arcDia, arcDia, 270, 90);
  gPath.AddLine(bottomRightPoint.X, rectY1, bottomRightPoint.X, rectY2);
  gPath.AddArc(rectX2 - arcRadius, rectY2 - arcRadius, arcDia, arcDia, 0, 90);
  gPath.AddLine(rectX2, bottomRightPoint.Y, ArrowPoints[0].X, bottomRightPoint.Y);
  gPath.AddLines(ArrowPoints);
  gPath.AddLine(ArrowPoints[2].X, bottomRightPoint.Y, rectX1, bottomRightPoint.Y);
  gPath.AddArc(topLeftPoint.X, rectY2 - arcRadius, arcDia, arcDia, 90, 90);
  gPath.AddLine(topLeftPoint.X, rectY2, topLeftPoint.X, rectY1);
  gPath.AddArc(topLeftPoint.X, topLeftPoint.Y, arcDia, arcDia, 180, 90);
 }
 gPath.CloseFigure();
 this.Region = new Region(this.gPath);
}

  ShowInfoWindow函數用來將提示視窗顯示出來,該函數需要將提示視窗附著的控制項和需要顯示的文本傳遞過來。然後,AnchorPointFromControl根據控制項的位置返回提示視窗的箭頭應該顯示的座標,代碼如下:

public static Point AnchorPointFromControl(Control anchorControl)
{
 if (anchorControl == null)
 throw new ArgumentException();
 Point controlLocation = anchorControl.Location;
 System.Drawing.Size controlSize = anchorControl.Size;

 if (anchorControl.Parent != null)
  controlLocation = anchorControl.Parent.PointToScreen(controlLocation);
 return controlLocation + new Size(controlSize.Width / 2, controlSize.Height / 2);
}

  PointToScreen表明將工作區點的位置映射成螢幕座標統一進行計算。上述代碼最後以行說明提示視窗的箭頭顯示在附著控制項的中點。

  將提示視窗的背景顏色設定成Info,外觀如:

  我們發現這樣的外觀有點彆扭,沒錯!因為提示視窗缺少黑色邊框!所以,還需要在表單的OnPaint事件中添加代碼,如下:

protected override void OnPaint(PaintEventArgs e)
{
 Pen p = new Pen(Color.Black , 2);
 e.Graphics.DrawPath(p, gPath);
 base.OnPaint(e);
}

 

  二、程式實現

  啟動Visual Studio 2005,建立Visual C#的Windows 應用程式項目,並取名為ShowInfoWindow,添加4個Button組件、1個Label組件、1個textBox組件和3個Panel組件,其中3個Button用來顯示標註式訊息提示視窗並分別附著在三個組件之上,代碼如下:

……
private InfoWindow iw;
……
private void button1_Click(object sender, EventArgs e)
{
 iw = new InfoWindow();
 iw.ShowInfoWindow(label1, "關於標籤組件的提示說明。");
}
private void button3_Click(object sender, EventArgs e)
{
 iw = new InfoWindow();
 iw.ShowInfoWindow(button2, "關於按鈕組件的提示說明。");
}

private void button4_Click(object sender, EventArgs e)
{
 iw = new InfoWindow();
 iw.ShowInfoWindow(textBox1, "關於文字框組件的提示說明。");
}

  然後,我們在項目中添加新Windows表單,取名為InfoWindow,將InfoWindow的BackColor設為Info,FormBorderStyle設為None,將ShowIcon和ShowInTaskbar都設為False,在表單上放置1個Label組件和1個Button組件,分別用來顯示訊息內容和關閉提示視窗的操作。具體實現請參見文章附帶的源碼,這裡不再詳述。

  三、總結

  本文示範了標註式訊息提示視窗的建立和顯示,利用GraphicsPath對象、Region對象以及螢幕座標映射等方法有效實現了提示視窗的外觀和樣式,提示視窗可以自動附著在相應控制項之上,並且根據附著控制項在螢幕上的位置自動調整提示視窗箭頭的位置和大小。示範程式在Windows XP SP2以及.Net 架構 2.0環境下運行通過。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.