【《WPF手冊》讀書筆記系列】第三章-內容的概念



作者:劉樹偉
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)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章