作者:劉樹偉
QQ:1584793892
查看完整內容及示例代碼,請訪問:www.iuishop.com
一、內容
在Window類100多個public property中,最重要的一個property是Content。類型爲Object,所以,幾乎所有Object都可以作爲Window的“內容”,但另一個Window對象除外,因爲WPF規定Window必須是“樹根”,而不可以是另一個Window對象的分支。
只能設定“一個”Object給Content property。
可以爲Window對象的FontFamily和FontSize property賦值來改變作爲Window內容的字符串的字體和大小:
FontFamily = new FontFamily("Comic Sans MS");
FontSize = 48;
Window的FontSize property默認值爲11,使用“與設備無關的單位”,也就是1/96英寸。
通過設置Window類的Background屬性可以設置窗口背景色;通過設置Foreground屬性,可以設置作爲內容的字符串的文字顏色,但如果內容是element的話,不會影響element的顏色(除非element會顯示文字,但如果文字是作爲element的Content的話,也不會有影響)。
通過設置Window類的ResizeMode = ResizeMode.NoResize;來禁止窗口Resize。
通過設置Window類的SizeToContent = SizeToContent.WidthAndHeight;來使窗口的大小正好與內容的大小一致。
Window設置Content屬性後,使用內容對象的ToString傳出來的字符串來呈現外觀。只有一個特例:
Content = new int[57];
窗口會顯示“Int32[]Array”,而ToString方法返回的卻是“System.Int32[]”.
當然,如果Content屬性的值是控件的話,會直接顯示控件,而不是控件的ToString返回的字符串:
Content = new Button();
窗口顯示一個與客戶區一樣大的按鈕。
WPF中,在Content property的世界中,分爲兩組對象:一組繼承自UIElement,另一組則不是。後面這一組的顯示結果,就是ToString方法的返回值;前面這一組,則是利用UIElement的OnRender來顯示。上面的Button正是用OnRender來顯示窗口內容的。當顯示ToString方法的返回值時,那麼ContentControl(這是Window的祖先類)會先創建一個Text Block類型的對象,以實際顯示出此字符串。
Image作爲Window的內容時。顯示格式(包括拉伸,對齊等)的設置是通過給Image對象的某些屬性賦值來完成的。這不同於MFC,MFC中的位圖沒有屬性,顯示格式的控制是通過調用不同的繪圖函數(BitBlt或StretchBlt)和指定位置參數來完成的。
注意區分ContentElement類和ContentControl類,ContentElement是控件,有Content property,有OnRender方法,可以顯示自己,而ContentElement對象一定要是其它可以顯示的對象的一部分(也就是說,必須是控件的內容),才能得以顯示。
當把Window的Content設置爲一個字符串時,整個字符串總是有相同的格式,你無法將其中的幾個字設定爲粗體或斜體(書上說內容設置爲一個字符串時,ContentControl會先創建一個Text Block類型的對象,以實際顯示此字符串,不過我用UI Spy測試,好像不太一樣。UI Spy中,總是把“內容”作爲父親,然後纔是Window,如果是Text Block作爲“內容”的話,Window下面還會出現這個Block,但如果字符串作爲“內容”的話,就不會出現了)。如果需要這麼做,就不要將Content設置爲字符串,而是設置成一個TextBlock類型的對象。TextBlock的Inlines屬性允許Add多個單詞、Inline對象及UIElement對象,顯示的時候,會按Add順序把它們拼成一個完整字符串。如果你Add了一個Button對象,那麼這個字符串中,就會出現一個Button。由於Bold和Italic構造函數只接受Inline對象,
而不接受字符串對象,所以要先爲每個Bold或Itlic對象使用Run的構造函數,這樣,每個Inline(這裏是單詞)就可以有各自的格式了。下面的代碼顯示了單擊一個單詞後,在普通格式和斜體間切換:
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Documents;
namespace XXX
{
class HelloMFC : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new HelloMFC());
}
HelloMFC()
{
Width = 1000;
Height = 600;
TextBlock text = new TextBlock();
text.FontSize = 32;
Content = text;
string strQuote = "To be, or not to be, that is the question";
string[] strWords = strQuote.Split();
foreach (string str in strWords)
{
Run run = new Run(str);
run.MouseDown += RunOnMouseDown;
text.Inlines.Add(run);
text.Inlines.Add(" ");
}
Button btn = new Button();
text.Inlines.Add(btn);
}
void RunOnMouseDown(object sender, MouseButtonEventArgs args)
{
Run run = sender as Run;
if (args.ChangedButton == MouseButton.Left)
{
run.FontStyle = (run.FontStyle == FontStyles.Italic) ? FontStyles.Normal : FontStyles.Italic;
}
}
}
}
以上的代碼中,每個單詞通過Run類來實現字體格式的轉換。
二、Image
顯示圖像的步驟:
1. 建立一個Uri對象,用來表示圖像的位置,可以是網絡上的圖像、資源中的圖像或者硬盤中的圖像。
2. 把Uri對象作爲BitmapImage的構造函數的參數,從來創建一個BitmapImage對象,並把此圖像讀入內存(WPF支持很多格式,如Gif, Tiff, Jpeg及Png等)。
3. 創建一個Image對象,並把BitmapImage對象賦值給Image對象的Source property。
這個Image對象就是可顯示的元素,你可以把它作爲窗口的Content,從而顯示它。
例:
Uri uri = new Uri("http://www.iuishop.com/1.jpg"); // 網絡路徑
Uri uri = new Uri("E:\\pic\\1.JPG"); // 絕對路徑,也可以在路徑前加“file://”:Uri uri = new Uri("file://E:\\pic\\1.JPG");另外,“\\”也可以換成“/”或“//”。
Uri uri = new Uri("1.JPG", UriKind.RelativeOrAbsolute); // 相對路徑,後面的UriKind.RelativeOrAbsolute(也可以是UriKind.Relative)一定要有,否則會有運行時錯誤。
BitmapImage bitmap = new BitmapImage(uri);
Image img = new Image();
m_img.Source = bitmap;
你也可以不用到構造BitmapImage對象的時候就指定Uri,而是在對象創建之後,通過爲BitmapImage對象的UriSource property賦值的方式,來指定Uri。不過如果你要這麼做,請在爲UriSource賦值前後,分別調用BitmapImage的BeginInit和EndInit方法:
BitmapImage bitmap = new BitmapImage();
bitmap.BeginInit();
bitmap.UriSource = uri;
bitmap.EndInit();
三、Environment
Environment類可以取得一些Windows的環境變量,比如Environment.windir可以取得類似於“C:\Windows”這樣的字符串。
本章結尾提供了一種自繪控件的方法:從FrameworkElement類(相當於CWnd)派生新類,然後override OnRender方法(相當於WM_PAINT)。