繼承自定義視窗

2022-03-07 06:37:45 字數 2452 閱讀 1271

繼承自定義視窗

author: 周銀輝

date: 2008-03-16

專案中有不少的彈出視窗,按照美工的設計其外邊框(包括最大化,最小化,關閉等按鈕)自然不同於window 自身的,但每個彈出框的外邊框都是一樣的。對其中乙個視窗而言,我們要取消其window 邊框,並在右上角擺上三個按鈕並編寫其點選事件等,但若每個彈出視窗都按照這種方式做一遍就太土了。我們想避免重複勞動,最自然的聯想到了「繼承」。但wpf 給我們找了若干麻煩,被挫敗了幾次。今天經過2 小時的奮戰,終於搞定了,分享一下。

假設我們寫好的父視窗類為basewindow ,對應basewindow.cs 和basewindow.xaml, 要繼承它的視窗為window1 ,對應window1.cs 和window1.xaml ,我們常常進行的動作是將vs 為我們自動生成的**中的如下語句:

複製**

public partial class window1 : window

修改成:

複製**

public partial class window1 : basewindow

但編譯後,你會得到乙個錯誤:window1 有著不同的基類。

這是因為在window1.xaml 中

複製**

我們的window 繼承了window 類,開啟window1.g.cs 也可以看到這一點(這是vs 自動生成的乙個中間檔案,可以在window1 的initializecomponent() 方法上「轉到定義」來跳轉到該檔案,也可以在obj"debug 目錄下找到)。這就使得我們的window1 同時繼承window 和basewindow 類,多繼承是不被允許的。

那麼自然地,需要修改window1.xaml ,將其中的根「window 」,修改成我們的basewindow :

複製**

心想,這下可以編譯通過了吧,抱歉,不行,又得到另乙個編譯錯誤:src:basewindow 不能是xaml 檔案的根,因為它是由xaml 定義的,目前我避免這個問題的辦法是讓basewindow 僅僅在c# 中定義(即,沒有basewindow.xaml, 只有basewindow.cs )。

ok ,編譯順利通過,繼承成功。

明顯,不能作為basewindow 的內容,這是因為繼承了basewindow 的子類視窗(比如window1 )會覆蓋basewindow 的內容。

假設basewindow 這樣編寫:

複製**

public basewindow()

當子類window1 如下定義時:

複製**

這樣以來window1 中的grid 和textblock 會覆蓋basewindow 的內容而僅僅看到「hi ,i am window1 」的文字塊而沒有最小化最大化以及關閉按鈕了。

事實上,我們應該反過來想,window 也是乙個控制項,與其他控制項一樣其外觀及其外觀中的視覺元素仍然是由其style 和controltemplate 來定義的。想到這裡,一切就變得簡單了,我們應該將視窗外邊框(包括最小化,最大化和關閉按鈕)定義在其template 中,其他一些屬性(比如是否支援透明等)定義在style 中

其template 如下:

複製**

其style 如下:

複製**

然後在basewindow 的建構函式中指定其style 為我們定義的樣式:

複製**

private void initializestyle()

這樣一來,所有繼承了basewindow 的窗體,都有我們統一定義的外觀了。

只有外觀還不夠,至少得有滑鼠事件吧。那最小化事件來說,要做的事情是找到定義在controltemplate 中的btnmin 這個button 控制項,然後當其被點選時該controltemplate 被應用到的那個窗體被最小化。

frameworktemplate.findname(string name, frameworkelement templatedparent) 方法可以做幫助我們找到指定的frameworktemplate 被應用到templatedparent 上後具有name 名稱的控制項。

複製**

button minbtn = (button)basewindowtemplate.findname("btnmin", this);

minbtn.click += delegate

;其他事件同理:)不過值得提醒的是,上面這樣的**應該在窗體的style 和template 被應用之後,比如你可以在loaded 後編寫使用上面的**而不是直接放在構造方法中,否則frameworktemplate.findname ()方法將返回null 。

WPF 自定義視窗

window類繼承自contentcontrol類。可以通過設定windowstyle none 完全移除視窗框架,從而建立乙個可完全定製的視窗,但是有各種各樣的不方便,所以本文使用windowchrome.windowchrome來自定義視窗 自定義視窗 參考遇到的一些難纏問題 屬性作用 值all...

介面 顯示自定義視窗

製作自定義視窗類 存在的問題 製作的視窗不能移動 如果要改進,可以參見 無標題視窗的移動 this m pmainwnd new wnd this m pmainwnd showwindow this m ncmdshow this m pmainwnd updatewindow 注意一定要 ret...

Qt自定義視窗事件

一 移動主介面 移動主介面是通過按住滑鼠左鍵進行標題欄拖動最終導致主介面移動 由於還有視窗伸縮功能,因此對於標題欄左部,頂部,右部應該騰出5畫素空間給視窗伸縮功能使用,即滑鼠移動到這5畫素空間之內的話,滑鼠形狀就會發生改變 暗示可以伸縮視窗 為什麼只有標題欄騰出5畫素空間,而其他部件 如工具欄 內容...