【《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)。

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