增添趣味: 給單調的 Windows 表單應用程式增添趣味

來源:互聯網
上載者:User

使用 Microsoft .NET Framework 可以輕鬆地建立基於 Windows 的應用程式:您只需建立表單、添加控制項,然後將表單串連到商務邏輯,這樣就可以了。但這樣的應用程式並不能為使用者提供真正需要的互動功能。例如,當發生重要的外來事件時,這類應用程式通常不會通知使用者。並且視窗的外觀相同 - 相同的戰艦灰色表單、相同的標準控制項、相同的感覺。十分單調!

使用 .NET Framework 和 GDI+,可以輕鬆地將某些樣式添加到您的應用程式中。您可以使用透明度、形狀不規則的視窗、通知表徵圖、快顯視窗、不同色彩配置等元素。通過精心運用這些設計項目,就可以在應用程式和使用者之間建立起更迷人的互動體驗。

裝點您的應用程式

您可以應用各種簡單的技術來美化應用程式。其中一種技術是使用通知視窗警報使用者發生重要事件,突出這些事件,並使用幹擾較少的方法通知使用者優先順序較低的事件。許多應用程式都有效地應用了此技術。例如,MSN Messenger 在工作列地區上使用快顯視窗,以在朋友已登入或嘗試聯絡您時通知您;Outlook 2003 通過案頭警報通知提示收到新的電子郵件。(這些警報還可以使使用者在項到達時刪除、標記或開啟項。)添加具有吸引力的表單和視窗(使用者可以使用它們進行互動)還會增強使用者對應用程式的體驗。例如,使用 Windows Media Player 可以應用自己的外觀,使用非標準矩形形狀的視窗。顯然,您不該對每個應用程式使用所有這些技術,但是通過明智地應用其中某些技術,可以建立增強使用者體驗的應用程式。

我將通過修改簡單的事件監視器應用程式來介紹如何以及何時應用這些技術。初始應用程式顯示所選城市的最新的天氣資料(請參閱圖 1)。此典型的基於 .NET 傳統型應用程式檢索 Web 服務的資料,並將結果顯示在使用標準 Windows 控制項的表單中。我使用的服務以及許多其他 Web 服務可以在 http://www.xmethods.net/(英文)中找到。

1 標準應用程式視窗

這不是一個特別友好的應用程式。您需要對天氣報告使用專用的螢幕地區,然後定期按 Update(更新)按鈕。我將在本文其餘部分增強該應用程式以說明如何建立更迷人的使用者體驗。最後,您將擁有一個持續啟動並執行天氣警報中心。它將監視特定的城市並在出現重要的天氣變化時通知您,而且它將打破那些單調的灰色應用程式的模式。您可以修改應用程式以作為工作列中的 Notify(通知)表徵圖運行、提供事件發生時的自訂彈出資訊、啟用自身以及使用具有自訂背景的自訂視窗形狀顯示其資訊。

返回頁首

刪除該主視窗依賴關係

首要任務是修改應用程式,以便它不再依賴主表單,而是在啟動時建立 Notify(通知)表徵圖。由於存在適當數量的啟動代碼,因此最好建立一個新類來處理應用程式層級的任務。您將檢查應用程式的多個副本、建立 Notify(通知)表徵圖、添加菜單和處理常式、啟動計時器、啟動訊息迴圈以及處理一些會話事件。

請務必在應用程式作為 Notify(通知)表徵圖運行時執行這些小任務,因為如果不正確清理,在結束時,工作列通知區域中很容易出現 Notify(通知)表徵圖的多個副本。這使得使用應用程式變得很難,而且會使那些嘗試確定哪個 Notify(通知)表徵圖屬於來自應用程式的哪個會話的使用者感到迷惑。

要緩解該問題,請首先防止運行應用程式的多個副本。通常的做法是建立一個指明應用程式正在啟動並執行全域 mutex(有關此問題的詳細介紹,請參閱本期 MSDNMagazine 中的 .NET Matters 專欄)。第一個執行個體獲得 mutex 上的一個鎖並將在應用程式持續期間儲存該鎖。後續副本嘗試獲得該鎖,但失敗了,然後退出了,如下所示:

Public Shared Sub Main()Dim appSingleton As New System.Threading.Mutex(False, _"SingleInstance WeatherAlert")If appSingleton.WaitOne(0, False) Then Application.Run()appSingleton.Close()End Sub

接下來,啟用應用程式中的 Windows XP 主題。毫無疑問,您肯定聽說過 EnableVisualStyles,但使用 .NET Framework 1.x 時,您必須添加一些用於啟用向後相容的額外代碼(此代碼對於 .NET Framework 2.0 不再是必需的)。在以前的作業系統中運行時調用 EnableVisualStyles 會終止程式,因為使用者將丟失 uxtheme.dll。您必須在應用主題之前先測試較新的作業系統,如下所示:

Private Shared Sub InitThemes()If (((Environment.OSVersion.Platform = PlatformID.Win32NT) _AndAlso (Environment.OSVersion.Version.Major >= 5)) _AndAlso (Environment.OSVersion.Version.Minor > 0)) ThenIf OSFeature.Feature.IsPresent(OSFeature.Themes) ThenApplication.EnableVisualStyles()End IfApplication.DoEvents()End IfEnd Sub

主應用程式類也建立 Notify(通知)表徵圖並運行主訊息迴圈。運行沒有主視窗的應用程式與運行具有主視窗的應用程式基底本相同 - 只需進行兩處更改。必須將調用 Application.Run(FormName) 改為調用 Application.Run(),以便啟動沒有任何主表單的訊息迴圈。如果使用者從未建立主視窗,則不需要建立不可見狀態的視窗;根本就不要建立主視窗。第二處更改是處理 SessionEnded 事件。如果使用者在應用程式運行時登出 Windows,則 Windows 將通過引發 SessionEnded 事件要求退出應用程式。如果不響應此事件,Windows 將假定應用程式剛剛出錯。Windows 將通知您的使用者您的應用程式未響應,並要求終止應用程式。要解決此問題,只需處理該事件並關閉應用程式。將處理常式附加到主應用程式,如下所示:

AddHandler Microsoft.Win32.SystemEvents.SessionEnded, _New Microsoft.Win32.SessionEndedEventHandler(AddressOf _ApplicationMain.SystemEvents_SessionEnded)將在該處理常式中進行正確清理:Private Shared Sub SystemEvents_SessionEnded(ByVal sender As Object, _ByVal e As Microsoft.Win32.SessionEndedEventArgs)If (Not _mainWindow Is Nothing) Then _mainWindow.Close()_icon.Visible = FalseApplication.Exit()End Sub

結束代碼中有一些項與標準 Windows 表單應用程式不同。首先,您需要檢查主視窗是否是在您關閉它之前建立的。使用者甚至可能未開啟主視窗。然後,您需要隱藏 Notify(通知)表徵圖。您是否曾使一個作為工作列表徵圖啟動並執行程式消失並留下灰顯的工作列表徵圖直到您試用並啟用它?一些開發人員忘記清理工作列了。在退出程式之前需要隱藏 Notify(通知)表徵圖。對於 Notify(通知)表徵圖,沒有 Close 方法;隱藏 Notify(通知)表徵圖時,該表徵圖將自我清理。

返回頁首

通知使用者

使用者將應用程式作為表徵圖運行時就是向使用者提供反饋的時間。您可以通過建立快顯視窗實現此目的。我不喜歡標準提示通知 - 我更喜歡其他樣式的通知,例如 Outlook 訊息通知或 MSN Messenger 連絡人登入通知。我希望對通知加以控制以通知使用者,而不影響正常的任務。

Outlook 2003 經適當配置後,在您收到電子郵件時,螢幕右下角將淡顯一個小視窗,其中顯示寄件者和郵件主題。您可以單擊此處以閱讀郵件、立即刪除郵件或設定後續標記。如果您很忙而郵件不緊急,您可以忽略該快顯視窗,允許它逐漸消失,將該郵件保留為未讀狀態,以稍後進行閱讀。

為天氣警報應用程式建立一個類似的視窗將會使使用者更輕鬆地接收天氣資訊更新。通知視窗本身會很簡短地顯示,如果使用者忽略該視窗,則該視窗將消失。不要建立那種需要使用者強制忽略的通知表單。如果使用者不在附近,或者使用者認為郵件不夠重要無需中斷當前任務,則該通知會消失。

2 通知框

我將視窗放在案頭的右下角處,通知表徵圖的正上方。快顯視窗應該逐漸顯示、顯示一會兒,然後逐漸消失。為了使該視窗更便於使用,如果使用者將滑鼠移動到視窗上,它將立即變得不透明,而且不會逐漸消失,除非使用者離開該視窗。如果使用者希望開啟主應用程式,可以單擊快顯視窗,應用程式將顯示主視窗。最後,若要添加一些樣式,可以使用漸層筆刷繪製背景,然後隱藏所有常見的視窗邊界(請參閱圖 2)。GDI+ 可以使此操作變得相當簡單。

返回頁首

使用 GDI+

建立透明、非矩形視窗需要幾個簡單的步驟。首先,將設計器中的 Form Border Style(表單邊界樣式)更改為 None(無)。該操作將刪除快顯視窗中的所有正常的非用戶端地區對象。沒有關閉框、系統功能表或尺寸柄。您還應該關閉“在工作列中顯示”設定。不希望快顯視窗顯示在工作列中。

使用一種稱為“色度鍵控”的技術可以實現透明度。色度鍵控映像將一種顏色指定為透明色。在繪製視窗時,不繪製與透明色匹配的所有像素。請務必選擇一種不可能在正常應用程式中使用的顏色。顯然,白色、黑色和灰色不是最好的選擇,因為它們的使用頻率很高。酸橙綠或淺黃綠色可能會好一些。使用 Visual Studio .NET 中的 Windows 表單內容可以設定通過 TransparencyKey 屬性呈現透明的顏色。有關色度鍵控的詳細資料,請參閱“色度鍵控、Alpha 值混合處理和透明度”提要欄。

設定透明度後,必須添加代碼才能繪製背景。要使用 GDI+ 實現的圓角矩形功能,可以使用圖形路徑。事實上,使用圖形路徑可以建立所需的任何不規則形狀。 3 中的代碼說明了用於建立圓角矩形路徑的方法。

背景利用另一個新的 GDI+ 功能 - 漸層筆刷。我使用線性漸層畫筆建立了所需的背景效果。首先,我用酸橙綠透明色填充了整個背景矩形,然後用線性漸層畫筆(從鋼青色到淺藍色)填充了內部圓角矩形。我是使用 OnPaintBackground 方法的替代方法完成所有這些工作的。使用替代方法比將事件處理常式附加到相關事件更為有效。

要完成繪製代碼,必須添加繪製文本的繪製處理常式。它將在其建構函式中繪製傳遞到快顯視窗的訊息。然後,您希望將字型設定為與系統定義的連結顏色和活動連結一致。當使用者進入快顯視窗時,將視窗字型更改為帶有底線的字型。當使用者離開該視窗時,還原為原來的字型。這會給使用者留下一種快顯視窗中的文本是一個連結的印象。

返回頁首

逐漸顯示和逐漸消失

下一步是添加計時器和處理常式以更新快顯視窗的不透明度。在設計器中,添加計時器並將快顯視窗的初始不透明度設定為 0%。計時器事件引發時,增加不透明度(我選擇了增加 0.05)。當不透明度達到 1 時,重設計時器以在 3 秒內引發,以便使用者有時間查看快顯視窗。然後,將計時器設定為較小的時間間隔,降低每次引發時的不透明度。不透明度達到 0 後,關閉視窗。

必須添加處理常式才能在使用者將滑鼠移到快顯視窗時停止逐漸顯示/逐漸消失進程。當然,使用者離開該視窗時要重新啟動逐漸消失進程。這裡只有一個要注意的問題。關閉框(請參閱圖 2)是子視窗。當使用者將滑鼠移到關閉框上時,主視窗將獲得 MouseLeave 訊息。

除了快顯視窗的滑鼠進入和滑鼠離開方法,還必須為快顯視窗中的所有子視窗添加事件處理常式。雖然您的確會在使用者在關閉框和父級快顯視窗之間移動時擷取進入和離開事件,但在擷取其他 MouseEnter 事件之前不會從一個視窗擷取 MouseLeave 訊息。這意味著您從一個視窗移到另一個視窗時不能使狀態出錯。使用者與快顯視窗互動時,該視窗不會消失。

在您離開快顯視窗執行之前,必須定義該視窗在您收到多個更新時的行為。在此樣本中,我採取了一種簡單的方式:如果快顯視窗顯示時發生第二個通知,只需忽略。商務應用程式採用不同的方法。Outlook 2003 建立了一系列快顯視窗,每個電子郵件一個視窗。MSN Messenger 將快顯視窗堆棧在螢幕上,直到達到案頭的頂端。此樣本並不會產生達到該程度的足夠的有趣通知。

返回頁首

設計應用程式的外觀

現在該將一些樣式應用到主視窗了(請參閱圖 4)。要達到效果,需要建立背景映像。任何一個您希望透明的位置都應以透明色繪製。在我的樣本中,我又將背景色選擇為酸橙綠。將背景映像設定為新的位元影像,將表單邊框樣式設定為 None(無),這樣就基本完成了。問題是當位元影像色彩深度與監視器色彩深度不一致時,有一些圖形卡阻止透明度起作用(有關詳細資料,請參閱知識庫文章 822495 BUG:The TransparencyKey Property Is Not Effective for Microsoft Windows Forms If the Color Depth of the Monitor Is Set to a Value That Is Greater Than 24-Bit(英文)。要解決此問題,必須將背景位元影像設定為透明。下面的代碼中顯示的 OnLoad 替代方法可以實現此操作。

Protected Overrides Sub OnLoad(ByVal e As EventArgs)Dim bitmapBG As Bitmap = _CType(BackgroundImage,Bitmap)bitmapBG.MakeTransparent(bitmapBG.GetPixel(0, 0))TransparencyKey = bitmapBG.GetPixel(0, 0)MyBase.OnLoad(e)End Sub

更新映像後,還必須更新透明度鍵以便與像素的已更改值匹配。

4 向主視窗添加樣式

然後,需要修改控制項,以便它們處於透明狀態,更好地顯示在背景中。我選擇了黃色字型以區別於背景映像。您可以在設計器或代碼中修改背景色,將其設定為 System.Drawing.Color.Transparent。背景映像將通過控制項顯示(請參閱圖 5)。

5 背景映像顯示方式

最後,它會協助使用者添加一種在螢幕周圍移動主視窗的機制。由於不再存在標題列,您可以讓使用者移動視窗,方法是在可見表單的任意位置按滑鼠左鍵並將視窗從一個位置拖到另一個位置。如果使用者拖動視窗,MouseMove 方法將移動該視窗:

Protected Overrides Sub OnMouseMove(ByVal e As MouseEventArgs)If _isMoving ThenLocation = New Point(Location.X + e.X - XOffset, Location.Y + e.Y - YOffset)End IfMyBase.OnMouseMove(e)End Sub

該方法很有用,除非使用者碰巧在其中一個子視窗(建立的用於顯示天氣資訊的視窗)中單擊了滑鼠。要使其發揮作用,必須建立一個按下滑鼠處理常式,指明使用者在某個子視窗中單擊滑鼠按鍵時的移動操作。但這並非對所有子視窗都有用 - 您仍然需要連結按鈕和關閉框的預設行為。同一方法可處理任何其他子控制項的所有 MouseDown 事件,如下所示:

Private Sub Child_MouseDown(ByVal sender As Object, _ByVal e As System.Windows.Forms.MouseEventArgs) Handles _labelAirPressure.MouseDown, labelDewPoint.MouseDown, _labelHumidity.MouseDown, labelLocation.MouseDown, _labelSkyConditions.MouseDown, labelTemperature.MouseDown, _labelVisibility.MouseDown, labelWind.MouseDownIf (e.Button = MouseButtons.Left) Then_isMoving = TrueXOffset = e.XYOffset = e.YEnd IfEnd Sub

添加關閉框和連結按鈕以擷取最新天氣資訊,這樣就完成了。

返回頁首

小結

建立需要以不同方式與使用者進行互動的應用程式時,突出它們,但不要過度。由於標準外觀已為使用者所熟悉,因此如果您打破了該模式,則理由必須充分。由於過多的應用程式將佔用系統工作列的空間,因此不要進行該操作,除非它確實是應用程式與使用者互動的最佳方法。否則,請使用其他方法宣傳您的應用程式。

相關文章

聯繫我們

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