WPF程序设计 :第三章 内容的概念(The Concept of Content)
2008-09-05 09:41
435 查看
Window类的Content是从ContentControl类继承来的。ContentControl继承自Control,而Window直接继承自ContentControl。ContentControl类存在的意义几乎就是为了定义Content property以及几个相关的property和方法。
Content property被定义成Object类型,这似乎暗示着它可以是任何对象,事实也相去不远。"相去不远"是因为你不可以把Content property设定成另一个Window类型的对象。运行时会报错,异常信息提醒开发者:Window必须是"树根",而不可以是另一个Window对象的分支。
实例程序-1:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
namespace PartThree
{
public class DisplaysomeText : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new DisplaysomeText());
}
public DisplaysomeText()
{
Title = "Display some Text";
Content = new int[57];//EventArgs.Empty;//DateTime.Now;//Math.PI;
Brush brush = new LinearGradientBrush(Colors.Black, Colors.White, new Point(0, 0), new Point(1, 1));
Background = brush;
Foreground = brush;
FontFamily = new FontFamily("Comic Sans MS");
FontSize = 50;
SizeToContent = SizeToContent.WidthAndHeight;
BorderBrush = Brushes.SaddleBrown;
BorderThickness = new Thickness(25, 50, 75, 100);
}
}
}
SizeToContent = SizeToContent.WidthAndHeight;
Window类的SizeToContent property造成窗口大小可以根据内容的尺寸作调整。
实例程序 - 2:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
namespace PartThree
{
public class RecordKeyStrokes : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new RecordKeyStrokes());
}
StringBuilder build = new StringBuilder("text");
public RecordKeyStrokes()
{
Title = "Record Key Strokes";
Content = build;
}
protected override void OnTextInput(System.Windows.Input.TextCompositionEventArgs e)
{
base.OnTextInput(e);
//string str = Content as string;
if (e.Text == "\b")
{
if (build.Length > 0)
{
build = build.Remove(build.Length - 1, 1);
}
}
else
{
build.Append(e.Text);
}
Content = null;
Content = build;
}
}
}
Content Property 真正需要的是本质上更图形化的东西,由UIElement继承而来的类的实例。
在WPF中,UIElement是一个极为重要的类。它实现键盘、鼠标以及手写笔(stylus)事件的处理。UIElement类也包含一个很重要的方法,名为OnRender。这个方法被调用,以显示对象的外观。(待会有实例程序)
(你可以看到在DrawingContent对象中包含很多Draw..的方法)
在Content property的世界中,分成两组对象:一组继承自UIElement,另一组则不是。后面一组的显示结果,就是ToString方法的返回值;前面这一组,则是利用OnRender来显示。继承自UIElement的类(以及对象)被称为element。对这句话的理解参见实例程序-1和实例程序-2。
唯一直接继承UIElement的类是FrameworkElement,在WPF中所有的element都是继承自FrameworkElement。理论上,UIELement提供关于关于用户界面和屏幕显示的必要结构。可以支持各种各样的编程框架(programming framework)。WPF正是这样的框架,它包含继承自FrameworkElement的所有类。
一个重要的类 Image,它是继承自FrameworkElement的一个很常见的类型。下面是它的继承层次:
Object
DispatcherObject(abstract)
DependencyObject
Visual(abstract)
UIElement
FrameworkElement
Image
Image(图像)类让你可以轻易地在文件(document)或者应用内包含影像。
实例程序 - 3,image
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Media;
namespace PartThree
{
public class ShowMyFace : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new ShowMyFace());
}
public ShowMyFace()
{
Title = "Show my face";
Uri uri = new Uri(@"D://MyFace.jpg");
BitmapImage bitmap = new BitmapImage(uri);
Image img = new Image();
img.Stretch = Stretch.None;
img.HorizontalAlignment = HorizontalAlignment.Center;
img.VerticalAlignment = VerticalAlignment.Center;
img.Source = bitmap;
img.Margin = new Thickness(192, 96, 48, 0);
//img.Width = 300;
//img.Height = 500;
Content = img;
//SizeToContent = SizeToContent.WidthAndHeight;
img.Opacity = 0.5;
Background=new LinearGradientBrush(Colors.Red,Colors.Blue,new Point(0,0),new Point(1,1));
img.LayoutTransform = new RotateTransform(45);
}
}
}
Uri uri = new Uri(System.IO.Path.Combine(Enviroment.GetEnviromentVariable("windir"),"Gone Fishing.bmp"));
Enviroment.GetEnviromentVariable("windir")方法取出"windir"环境变量,其值看起来像是"C:\\WINDOWS"这样的字符串。Path Combine方法结合图片文件的路径名称和文件名,这样就不用费心正确地插入斜杠了。
Image类不具有自己的Background和Foreground property,因为这两个property是由Control类所定义的,而Image并非继承自Control。在早期Winows API中,几乎屏幕上所有的东西,都被认为是控件(Control),现在却不是如此。
控件是视觉对象(visual object),其特征是对用户的输入有反应,像Image这样的element,当然可以得到用户的输入,因为所有的键盘、鼠标、手写笔的输入事件都是由UIElement所定义的。
下面是System.Windows.Shapes这个命名空间,它包含名为Shape的抽象类,以及6个子类。
Object
DispatcherObject(abstract)
DependencyObject
Visual(abstract)
UIElement
FrameworkElement
Shape(abstract)
Ellipse
Line
Path
Polygon(多边形)
Polyline(多叉线)
Rectangle
虽然Image是现实点阵图像(raster图像)的标准做法,这些Shape类实现了简单的二维(two-dimensional)矢量图(Vector graphic) 。线面的程序创建一个椭圆(Ellipse)类的对象。
实例程序 - 4, Ellipse
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Shapes;
using System.Windows.Media;
namespace PartThree
{
public class ShapeAnEllipse : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new ShapeAnEllipse());
}
Ellipse elips;
public ShapeAnEllipse()
{
Title = "Shape an Ellipse";
elips = new Ellipse();
elips.Fill = Brushes.AliceBlue;
elips.StrokeThickness = 24;
elips.Width = 300;
elips.Height = 300;
elips.Stroke = new LinearGradientBrush(Colors.CadetBlue, Colors.Chocolate, new Point(1, 0), new Point(0, 1));
//elips.HorizontalAlignment = HorizontalAlignment.Stretch;
//elips.VerticalAlignment = VerticalAlignment.Stretch;
Content = elips;
}
protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
{
base.OnMouseDown(e);
double a = elips.ActualHeight;
}
}
}
该椭圆会填满客户区。周长是1/4英寸粗且使用了渐变画刷。(椭圆内部使用的是AliceBlue画刷来着色,这个颜色是以美国总统罗斯福的女儿来命名的)。
注意的是:不管是Shape类还是Ellispe类,都没有定义任何property可以让我们用来设定椭圆的尺寸,但是Ellispe类从FrameworkElement继承到的Width和Height property,这两个property正式作此用的:
elips.Wdith = 300;
elips.Height = 300;
上面实例程序,如何将Window的Conteng property 设定为字符串,以及如何设定此文字的font。然而,你直接设定到Content property的文字,总具有相同的格式,比方说,你无法将其中几个字设定格式如粗体或斜体。
如果你需要这样,就不要将Content property设定成字符串,而不是设定成一个TextBlock类型的对象,请看下面实例程序:
实例程序 - 5:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace PartThree
{
public class FormatTheText : Window
{
public FormatTheText()
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new FormatTheText());
}
Title = "Format The Text";
TextBlock txt = new TextBlock();
txt.FontSize = 32;
txt.Inlines.Add("This is some");
txt.Inlines.Add(new Italic(new Run("italic")));
txt.Inlines.Add("text ,and this is some ");
txt.Inlines.Add(new Bold(new Run("bold")));
txt.Inlines.Add("text,and let's cap it off with some ");
txt.Inlines.Add(new Bold(new Italic(new Run("bold italic"))));
txt.Inlines.Add("text.");
txt.TextWrapping = TextWrapping.Wrap;
Content = txt;
}
}
}
其实,当你将Content property设定成字符串,那么ContentControl(这是Window的祖先类)会先创建一个Text Block类型的对象,以实际显示出此字符串,Text Block类直接继承自FrameworkElement,它定义了Inlines property(类型为InlineCollection,这是Inline对象的collection)。
TextBlock本省属于System.Windows.Controls命名空间。但是 Inline是属于System.Windows.Document命名空间,而且甚至不是继承自UIElement。下面是部分的类继承图,显示出Inline和它的 后代:
Object
DispatcherObject(abstract)
DependencyObject
ContentElement
FrameworkContentElement
TextElement(abstract)
Inline(abstract)
Run
Span
Bold
Italic
UnderLine
你可能注意到这个类层次与之前的似乎有类似的结构 ---- ContentElement 和 FrameworkContentElement 类对比于 UIElement和FrameworkElement类。然而,ContentElement类不包含OnRender方法。继承自ContentElement的类所产生的对象,不会在屏幕上把自己画出来。它们却是要通过"继承自UIElement的类"才能在屏幕上达到视觉的演示,由"继承自UIElement的类"提供他们所欠缺的OnRender方法。
还有一点,不要把ContentElement 类和ContentControl混为一谈。ContentControl是控件,像Window一样,可以具有Content property。就算 Content property是空的,ContentControl对象还是会在屏幕上显示自己。而ContentElment对象一定要是其他可以显示的对象的一部分(也就是说,必须是控件的内容),才能得以显示。
类似UIElement类,ContentElement类定义了许多用户输入事件,可以把事件处理器(event handler)安装到"由TextBlock显示出来的" Inline elements上.下面的程序展示此技巧。
实例程序 - 6:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
namespace PartThree
{
public class ToggleBoldAndOtalic : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new ToggleBoldAndOtalic());
}
public ToggleBoldAndOtalic()
{
Title = "Toggle Bold & Italic";
TextBlock txt = new TextBlock();
txt.FontSize = 32;
txt.HorizontalAlignment = HorizontalAlignment.Center;
txt.VerticalAlignment = VerticalAlignment.Center;
Content = txt;
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();
run.Text = str;
run.MouseDown += new System.Windows.Input.MouseButtonEventHandler(run_MouseDown);
txt.Inlines.Add(run);
txt.Inlines.Add(" ");
}
}
void run_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Run run = sender as Run;
if (e.ChangedButton == MouseButton.Left)
run.FontStyle = run.FontStyle == FontStyles.Italic ? FontStyles.Normal : FontStyles.Italic;
if (e.ChangedButton == MouseButton.Right)
run.FontWeight = run.FontWeight == FontWeights.Bold ? FontWeights.Normal : FontWeights.Bold;
}
}
}
前面其实提到,窗口的Content property其实想要的是继承自UIElement类的实例,因为此类定义了一个名为OnRender的方法,负责在屏幕上显示此对象。
下面这个实例程序,让SimpleEllipse继承自FrameworkElement(这是直接继承自UIElement类的唯一类别),他相当重要的OnRender方法予以override,以获得一个DrawingContent对象。通过此对象和DrwingEllipse方法就可以绘制椭圆了。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace PartThree
{
public class SimpleEllispe : FrameworkElement
{
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
drawingContext.DrawEllipse(Brushes.Blue, new Pen(Brushes.Blue, 24), new Point(RenderSize.Width / 2, RenderSize.Height / 2), RenderSize.Width / 2, RenderSize.Height / 2);
drawingContext.
}
}
public class RenderTheGraphic : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new RenderTheGraphic());
}
public RenderTheGraphic()
{
Title = "Render the Graphic";
SimpleEllispe elips = new SimpleEllispe();
elips.Width = 120;
elips.Height = 100;
Content = elips;
}
}
}
总结:虽然本章使用到了System.Windows.Controls命名空间的element,但是没有使用任何继承自Control的类(当然Window本省是个例外)。控件是设计来获得用户的输入,并作出反应的。下一章,我们来展开这一范畴。
Content property被定义成Object类型,这似乎暗示着它可以是任何对象,事实也相去不远。"相去不远"是因为你不可以把Content property设定成另一个Window类型的对象。运行时会报错,异常信息提醒开发者:Window必须是"树根",而不可以是另一个Window对象的分支。
实例程序-1:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
namespace PartThree
{
public class DisplaysomeText : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new DisplaysomeText());
}
public DisplaysomeText()
{
Title = "Display some Text";
Content = new int[57];//EventArgs.Empty;//DateTime.Now;//Math.PI;
Brush brush = new LinearGradientBrush(Colors.Black, Colors.White, new Point(0, 0), new Point(1, 1));
Background = brush;
Foreground = brush;
FontFamily = new FontFamily("Comic Sans MS");
FontSize = 50;
SizeToContent = SizeToContent.WidthAndHeight;
BorderBrush = Brushes.SaddleBrown;
BorderThickness = new Thickness(25, 50, 75, 100);
}
}
}
SizeToContent = SizeToContent.WidthAndHeight;
Window类的SizeToContent property造成窗口大小可以根据内容的尺寸作调整。
实例程序 - 2:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
namespace PartThree
{
public class RecordKeyStrokes : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new RecordKeyStrokes());
}
StringBuilder build = new StringBuilder("text");
public RecordKeyStrokes()
{
Title = "Record Key Strokes";
Content = build;
}
protected override void OnTextInput(System.Windows.Input.TextCompositionEventArgs e)
{
base.OnTextInput(e);
//string str = Content as string;
if (e.Text == "\b")
{
if (build.Length > 0)
{
build = build.Remove(build.Length - 1, 1);
}
}
else
{
build.Append(e.Text);
}
Content = null;
Content = build;
}
}
}
Content Property 真正需要的是本质上更图形化的东西,由UIElement继承而来的类的实例。
在WPF中,UIElement是一个极为重要的类。它实现键盘、鼠标以及手写笔(stylus)事件的处理。UIElement类也包含一个很重要的方法,名为OnRender。这个方法被调用,以显示对象的外观。(待会有实例程序)
(你可以看到在DrawingContent对象中包含很多Draw..的方法)
在Content property的世界中,分成两组对象:一组继承自UIElement,另一组则不是。后面一组的显示结果,就是ToString方法的返回值;前面这一组,则是利用OnRender来显示。继承自UIElement的类(以及对象)被称为element。对这句话的理解参见实例程序-1和实例程序-2。
唯一直接继承UIElement的类是FrameworkElement,在WPF中所有的element都是继承自FrameworkElement。理论上,UIELement提供关于关于用户界面和屏幕显示的必要结构。可以支持各种各样的编程框架(programming framework)。WPF正是这样的框架,它包含继承自FrameworkElement的所有类。
一个重要的类 Image,它是继承自FrameworkElement的一个很常见的类型。下面是它的继承层次:
Object
DispatcherObject(abstract)
DependencyObject
Visual(abstract)
UIElement
FrameworkElement
Image
Image(图像)类让你可以轻易地在文件(document)或者应用内包含影像。
实例程序 - 3,image
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media.Imaging;
using System.Windows.Controls;
using System.Windows.Media;
namespace PartThree
{
public class ShowMyFace : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new ShowMyFace());
}
public ShowMyFace()
{
Title = "Show my face";
Uri uri = new Uri(@"D://MyFace.jpg");
BitmapImage bitmap = new BitmapImage(uri);
Image img = new Image();
img.Stretch = Stretch.None;
img.HorizontalAlignment = HorizontalAlignment.Center;
img.VerticalAlignment = VerticalAlignment.Center;
img.Source = bitmap;
img.Margin = new Thickness(192, 96, 48, 0);
//img.Width = 300;
//img.Height = 500;
Content = img;
//SizeToContent = SizeToContent.WidthAndHeight;
img.Opacity = 0.5;
Background=new LinearGradientBrush(Colors.Red,Colors.Blue,new Point(0,0),new Point(1,1));
img.LayoutTransform = new RotateTransform(45);
}
}
}
Uri uri = new Uri(System.IO.Path.Combine(Enviroment.GetEnviromentVariable("windir"),"Gone Fishing.bmp"));
Enviroment.GetEnviromentVariable("windir")方法取出"windir"环境变量,其值看起来像是"C:\\WINDOWS"这样的字符串。Path Combine方法结合图片文件的路径名称和文件名,这样就不用费心正确地插入斜杠了。
Image类不具有自己的Background和Foreground property,因为这两个property是由Control类所定义的,而Image并非继承自Control。在早期Winows API中,几乎屏幕上所有的东西,都被认为是控件(Control),现在却不是如此。
控件是视觉对象(visual object),其特征是对用户的输入有反应,像Image这样的element,当然可以得到用户的输入,因为所有的键盘、鼠标、手写笔的输入事件都是由UIElement所定义的。
下面是System.Windows.Shapes这个命名空间,它包含名为Shape的抽象类,以及6个子类。
Object
DispatcherObject(abstract)
DependencyObject
Visual(abstract)
UIElement
FrameworkElement
Shape(abstract)
Ellipse
Line
Path
Polygon(多边形)
Polyline(多叉线)
Rectangle
虽然Image是现实点阵图像(raster图像)的标准做法,这些Shape类实现了简单的二维(two-dimensional)矢量图(Vector graphic) 。线面的程序创建一个椭圆(Ellipse)类的对象。
实例程序 - 4, Ellipse
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Shapes;
using System.Windows.Media;
namespace PartThree
{
public class ShapeAnEllipse : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new ShapeAnEllipse());
}
Ellipse elips;
public ShapeAnEllipse()
{
Title = "Shape an Ellipse";
elips = new Ellipse();
elips.Fill = Brushes.AliceBlue;
elips.StrokeThickness = 24;
elips.Width = 300;
elips.Height = 300;
elips.Stroke = new LinearGradientBrush(Colors.CadetBlue, Colors.Chocolate, new Point(1, 0), new Point(0, 1));
//elips.HorizontalAlignment = HorizontalAlignment.Stretch;
//elips.VerticalAlignment = VerticalAlignment.Stretch;
Content = elips;
}
protected override void OnMouseDown(System.Windows.Input.MouseButtonEventArgs e)
{
base.OnMouseDown(e);
double a = elips.ActualHeight;
}
}
}
该椭圆会填满客户区。周长是1/4英寸粗且使用了渐变画刷。(椭圆内部使用的是AliceBlue画刷来着色,这个颜色是以美国总统罗斯福的女儿来命名的)。
注意的是:不管是Shape类还是Ellispe类,都没有定义任何property可以让我们用来设定椭圆的尺寸,但是Ellispe类从FrameworkElement继承到的Width和Height property,这两个property正式作此用的:
elips.Wdith = 300;
elips.Height = 300;
上面实例程序,如何将Window的Conteng property 设定为字符串,以及如何设定此文字的font。然而,你直接设定到Content property的文字,总具有相同的格式,比方说,你无法将其中几个字设定格式如粗体或斜体。
如果你需要这样,就不要将Content property设定成字符串,而不是设定成一个TextBlock类型的对象,请看下面实例程序:
实例程序 - 5:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
namespace PartThree
{
public class FormatTheText : Window
{
public FormatTheText()
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new FormatTheText());
}
Title = "Format The Text";
TextBlock txt = new TextBlock();
txt.FontSize = 32;
txt.Inlines.Add("This is some");
txt.Inlines.Add(new Italic(new Run("italic")));
txt.Inlines.Add("text ,and this is some ");
txt.Inlines.Add(new Bold(new Run("bold")));
txt.Inlines.Add("text,and let's cap it off with some ");
txt.Inlines.Add(new Bold(new Italic(new Run("bold italic"))));
txt.Inlines.Add("text.");
txt.TextWrapping = TextWrapping.Wrap;
Content = txt;
}
}
}
其实,当你将Content property设定成字符串,那么ContentControl(这是Window的祖先类)会先创建一个Text Block类型的对象,以实际显示出此字符串,Text Block类直接继承自FrameworkElement,它定义了Inlines property(类型为InlineCollection,这是Inline对象的collection)。
TextBlock本省属于System.Windows.Controls命名空间。但是 Inline是属于System.Windows.Document命名空间,而且甚至不是继承自UIElement。下面是部分的类继承图,显示出Inline和它的 后代:
Object
DispatcherObject(abstract)
DependencyObject
ContentElement
FrameworkContentElement
TextElement(abstract)
Inline(abstract)
Run
Span
Bold
Italic
UnderLine
你可能注意到这个类层次与之前的似乎有类似的结构 ---- ContentElement 和 FrameworkContentElement 类对比于 UIElement和FrameworkElement类。然而,ContentElement类不包含OnRender方法。继承自ContentElement的类所产生的对象,不会在屏幕上把自己画出来。它们却是要通过"继承自UIElement的类"才能在屏幕上达到视觉的演示,由"继承自UIElement的类"提供他们所欠缺的OnRender方法。
还有一点,不要把ContentElement 类和ContentControl混为一谈。ContentControl是控件,像Window一样,可以具有Content property。就算 Content property是空的,ContentControl对象还是会在屏幕上显示自己。而ContentElment对象一定要是其他可以显示的对象的一部分(也就是说,必须是控件的内容),才能得以显示。
类似UIElement类,ContentElement类定义了许多用户输入事件,可以把事件处理器(event handler)安装到"由TextBlock显示出来的" Inline elements上.下面的程序展示此技巧。
实例程序 - 6:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
namespace PartThree
{
public class ToggleBoldAndOtalic : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new ToggleBoldAndOtalic());
}
public ToggleBoldAndOtalic()
{
Title = "Toggle Bold & Italic";
TextBlock txt = new TextBlock();
txt.FontSize = 32;
txt.HorizontalAlignment = HorizontalAlignment.Center;
txt.VerticalAlignment = VerticalAlignment.Center;
Content = txt;
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();
run.Text = str;
run.MouseDown += new System.Windows.Input.MouseButtonEventHandler(run_MouseDown);
txt.Inlines.Add(run);
txt.Inlines.Add(" ");
}
}
void run_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Run run = sender as Run;
if (e.ChangedButton == MouseButton.Left)
run.FontStyle = run.FontStyle == FontStyles.Italic ? FontStyles.Normal : FontStyles.Italic;
if (e.ChangedButton == MouseButton.Right)
run.FontWeight = run.FontWeight == FontWeights.Bold ? FontWeights.Normal : FontWeights.Bold;
}
}
}
前面其实提到,窗口的Content property其实想要的是继承自UIElement类的实例,因为此类定义了一个名为OnRender的方法,负责在屏幕上显示此对象。
下面这个实例程序,让SimpleEllipse继承自FrameworkElement(这是直接继承自UIElement类的唯一类别),他相当重要的OnRender方法予以override,以获得一个DrawingContent对象。通过此对象和DrwingEllipse方法就可以绘制椭圆了。
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Windows.Shapes;
namespace PartThree
{
public class SimpleEllispe : FrameworkElement
{
protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
{
drawingContext.DrawEllipse(Brushes.Blue, new Pen(Brushes.Blue, 24), new Point(RenderSize.Width / 2, RenderSize.Height / 2), RenderSize.Width / 2, RenderSize.Height / 2);
drawingContext.
}
}
public class RenderTheGraphic : Window
{
[STAThread]
public static void Main()
{
Application app = new Application();
app.Run(new RenderTheGraphic());
}
public RenderTheGraphic()
{
Title = "Render the Graphic";
SimpleEllispe elips = new SimpleEllispe();
elips.Width = 120;
elips.Height = 100;
Content = elips;
}
}
}
总结:虽然本章使用到了System.Windows.Controls命名空间的element,但是没有使用任何继承自Control的类(当然Window本省是个例外)。控件是设计来获得用户的输入,并作出反应的。下一章,我们来展开这一范畴。
相关文章推荐
- WPF 学习记录——The Concept of Content
- (WPF学习记录)第三章 Content的概念
- 访问字符串对象的内容(Accessing the Content of String Objects)CFString
- <<iText in Action 2nd>>3.1节(Introducing the concept of direct content)读书笔记
- Adapter的The content of the adapter has changed问题分析
- 处理The content of the adapter has changed but ListView did not receive a notification异常
- The content of element type "beans" must match "(description?,(import|alias|bean)*)
- 解决问题The content of the adapter has changed but ListView did not receive a notification.
- The content of element type "configuration" must match "(properties?,settings?,typeAliases?,typeHand
- Extend the CPS concept, remodel the company organization 扩展CPS概念,对企业信息系统进行重新建模
- JavaScript 高级程序设计——第三章基本概念 学习笔记
- Bjarne Stroustrup Expounds on Concepts and the Future of C++
- How to remove the icon of a WPF window
- The content of element type "resultMap" must match "(constructor?,id*,result*,association*,collect
- 【遇见Android bug】The content of the adapter has changed but ListView did not receive a notification
- place content in the center of pdf
- 【WPF】The example of progress bar, label status changed by background worker
- The content of element type "package" mustmatch "(result-types?,interceptors?,default-interceptor-re
- the table of content-type
- (转)HttpWebRequest以UTF-8编码写入内容时发生“Bytes to be written to the stream exceed the Content-Length bytes size specified.”错误