1-2章

来源:互联网 发布:sql回退 编辑:程序博客网 时间:2024/05/16 18:16

WPF程序设计读书笔记(1-2)


 

虽然刚刚所显示的程序没有什么不对的地方,但在只有代码(不写XAML标记)的WPF程序中,更常见的是定义一个Window的子类,而非定义Application的子类。下面是一个很典型的单一代码文件程序:
//*********************************************************
//InheritTheWin.cs 2010 17th July by mouyong
//*********************************************************
using System;
using System.Windows;
using System.Windows.Input;
 
namespace part1.ch01
{
    class InheritTheWin:Window
    {
        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new InheritTheWin());
        }
 
        public InheritTheWin()
        {
            Title="继承窗口";
        }
    }
}
这本书中的很多范例都是使用上面的结构。如果你想要将Main方法尽可能精简,还可以将所有的调用都放在同一条语句中:
new Application().Run(new InheritTheWin());
我们来看看还可以怎样完善这个程序,你可以跟着做,也可以按自己的想法,那样更好。
此窗口摆放的位置和大小,是由Windows操作系统决定的,但你也可以改变它。Windows类从FrameworkElement继承了WidthHeight属性,你可以在构造函数中设定这些属性:
width=288;
height=192;
其实这两个属性也可以设置为double,不一定非要是int
width=100*Math.PI;
height=100*Math.E;
widthheight属性一开始都是没有定义的,如果你在程序中没有设定这两个属性,那么它们就会一直没有定义,也就是说,它们的值是NaNNaN的意思就是“非数字”(Not a Number)
所以,如果你需要取得窗口的实际尺寸,你应该使用ActualWidthActualHeight这两个只读属性。如果它们都为0,说明窗口尚未显示出来。
也许你会认为前面输入的宽和高的单位应该是像素,这是一个错误的想法,因为如果是像素,就不可能使用double类型来表示,只能使用int类型。这里使用的是一个“逻辑单位”,以保证在任意的显示分辨率下,你看到窗口的大小始终保持一致(即在低分辨率下它所包含的像素就少,高分辨率下它所包含的就像素就会增多)。
WPF中,普通地使用这些与设备无关的单位。比如前面显示的鼠标的位置,也不是以像素为单位的,而是这个与设备无关的“逻辑单位”(默然说话:我记得原来在VB中这个单位叫“缇”,不知道这里是不是仍然沿用这个名称
当然widthheight是不能被设置为无限小的,你可以利用SystemParameters.MinimumWindowWidthSystemParameters.MinimumWindowHeight这两个只读属性来查看窗口的最小尺寸是多少(单位依旧是前面所提到的“逻辑单位”)
如果你想把窗口放置到一个指定的位置,你可以利用Window类的LeftTop属性:
Left=500;
Top=250;
这两个属性用来指定窗口左上角的坐标,也是使用与设备无关的单位(double),如果没有赋值,它们的值也会是NaN
你可以使用SystemParameters.PrimaryScreenWidthSystemParameters.PrimaryScreenHeight来获得屏幕的显示分辨率,不过它们仍然是使用的与设备无关的单位,而不是像素。这样也有好处,如果你需要用到屏幕的宽和高来进行窗口的位置和尺寸的设置时,你可以直接计算,而不用做任何转换。例如:
Left=SystemParameters.PrimaryScreenWidth-Width;
Top= SystemParameters.PrimaryScreenHeight-Height;
以上代码将窗口置于屏幕右下角。有两个问题需要注意,一个是由于代码中引用了WidthHieght,所以你需要在执行这两句代码之前给它们赋值,否则后果你可能不太喜欢。另一个是,如果你的任务栏显示在屏幕下方,那它会遮住窗口的一部分。其实你可能并非想把窗口放到屏幕的右下角,而是工作区的右下角。而工作区就是桌面除任务栏以外的部分。所以,你的代码可以换成这样:
Left = SystemParameters.WorkArea.Width - Width;
Top = SystemParameters.WorkArea.Height - Height;
SystemParameters.WorkArea返回一个Rect类型的对象,它包括了工作区的位置和宽高。
放置在工作区中间的代码如下:
Left = (SystemParameters.WorkArea.Width - Width) / 2 + SystemParameters.WorkArea.Left ;
Top = (SystemParameters.WorkArea.Height - Height) / 2 + SystemParameters.WorkArea.Top ;
其实要将一个窗口放置于工作区的中间有很简单的办法,你可以使用Window类的WindowStartupLocation属性,它的值属于WindowStartupLocation枚举类型,代码如下:
this.WindowStartupLocation = WindowStartupLocation.CenterScreen;
虽然枚举值叫“CenterScreen”,但其实是工作区的中间。WindowStartupLocation还有很多的枚举值,它们可以让Windows操作系统帮助你计算你的个窗口摆放的位置。
下面的一个小程序是将窗口放在工作区的中间,每次按下“上键”或“下键”,就会将窗口尺寸增减百分之十。
//*********************************************************
//GrowAndShrink.cs 2010 17th July by mouyong
//*********************************************************
using System;
using System.Windows;
using System.Windows.Input;
 
 
namespace part1.ch01
{
    class GrowAndShrink:Window
    {
        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new GrowAndShrink());
        }
        public GrowAndShrink()
        {
            Title = "缩放窗体";
            WindowStartupLocation = WindowStartupLocation.CenterScreen;
            Width = 192;
            Height = 192;
        }
        protected override void OnKeyDown(KeyEventArgs e)
        {
            base.OnKeyDown(e);
 
            if (e.Key == Key.Up)
            {
                Left -= 0.05 * Width;
                Top -= 0.05 * Height;
                Width *= 1.1;
                Height *= 1.1;
            }
            else if (e.Key == Key.Down)
            {
                Left += 0.05 * (Width/=1.1);
                Top += 0.05 * (Height/=1.1);
            }
          
        }
    }
}
任意键按下都会触发OnKeyDown事件方法被执行。每次你按下并放开键盘,OnKeyDownOnKeyUp都会被执行。两个方法都提供KeyEventArgs对象,它有一个Key属性可以让你知道哪个键被按下了,所以你可以很轻易的就重写这两个方法并完成你想要完成的任务。
如果你想获得按下了哪个功能键(象前面用到的上下键,或者是F1之类的键),OnKeyDownOnKeyUp非常有用。如果你想要从键盘获得Unicode字符,那就应该通过重写OnTextInput方法。它有一个TextCompositionEventArgs参数,这个参数有一个Text属性,是一个Unicode字符串。一般来说,它只有一个字符,但是语音和手写输入法也可能会调用OnTextInput,这种情况下,字符串有可能会稍微长一些。
下面的程序没有设定Title属性,而是让用户自行输入:
//*********************************************************
//TypeYourTitle.cs 2010 18th July by mouyong
//*********************************************************
using System;
using System.Windows;
using System.Windows.Input;
 
namespace part1.ch01
{
    class TypeYourTitle:Window
    {
        [STAThread]
        public static void Main()
        {
            Application app = new Application();
            app.Run(new TypeYourTitle());
        }
 
        protected override void OnTextInput(TextCompositionEventArgs e)
        {
            base.OnTextInput(e);
            if (e.Text == "/b" && Title.Length > 0)
            {
                Title = Title.Substring(0,Title.Length-1); //在标题栏有字符时,让退格键起作用
            }
            else if (e.Text.Length > 0 && !Char.IsControl(e.Text[0])) //如果你按下了CtrlAlt,那么就不能输入字符了
            {
                Title += e.Text;
            }
        }
    }
}
此方法允许的唯一控制字符是退格键(“/b”),只有当Title至少有一个字符长时,退格才会起作用。此方法就只是将从键盘输入的文字加入到Title属性的后面。
Window类还有一个重要的属性,就是Background。这是WindowControl过来的,负责掌管客户区的颜色。不过对于Background属性来说“颜色”不具有足够的表现力。所以,Backgroug属性是一个Brush(画刷)类型的对象,“彩绘窗口的画刷”可以有很多变化,包括渐变(gradient)画刷与位图(bitmap)画刷。画刷对于WPF相当重要,所以本书特别用了两章的篇幅来介绍。这两章的第一章,就是下一章,现在就让我们开始讨论画刷吧。

——摘自 牟勇的笔记

原创粉丝点击