您的位置:首页 > 其它

跟着小王学wpf系列之四 内容

2011-04-04 00:23 417 查看
六:内容的概念(Content)

Window类有100多个属性,最重要的一个属性就是Content.他表示这个window要显示的内容的集合。因为这个Content是一个object类型,所有你可以把任何东西交给他,然后让window显示。(不能将这个内容设置为一个window对象)。

class MyWindow:Window

{

public MyWindow()

{

Content = "Test Content";

}

}

在窗口的左上角点,会显示出Test Content。

如果相对输出的内容进行一些其他的调整该怎么办?

class MyWindow:Window

{

public MyWindow()

{

Brush bh = new LinearGradientBrush(Colors.Red, Colors.Blue, new Point(0, 0), new Point(1, 1));

Brush bh1 = new LinearGradientBrush(Colors.Khaki, Colors.Indigo, new Point(0, 0), new Point(1, 1));

Content = "";

FontFamily = new FontFamily("Comic Sans MS");//选择字体

FontSize = 100;//字的大小

FontStyle = FontStyles.Italic;//提供字体的风格

FontWeight = FontWeights.ExtraLight;//设置字体的粗细

//背景和字体都用同样的画刷但是不需要担心字看不见

//因为画刷在渲染区域的时候,选取的区域是不同的

//第一个画刷渲染背景是以用户工作区为选择区域

//第二个画刷渲染内容,是以内容所占的区域为选择区域。

Background = bh;

Foreground = bh1;

SizeToContent = SizeToContent.WidthAndHeight;

}

/// <summary>

/// 极度不推荐的一个方法,因为每次都要执行 s += e.Text;都会产生一个新的字符串对象

/// </summary>

/// <param name="e"></param>

protected override void OnTextInput(TextCompositionEventArgs e)

{

base.OnTextInput(e);

String s = Content as String;

if (s!=null)

{

if (e.Text == "\b")

{

s = s.Substring(0, s.Length - 1);

}

else

{

s += e.Text;

}

Content = s;

}

}

}

上面这个程序可以接受用户的输入,并把它显示在窗口上。

七:Content中存储的是什么?

Content中仅仅存储的是字符串吗?当然不是,他存储的更加图像化的东西。Content实际上是存储的一个UIElement对象的实例或者UIElement子类的实例。对于属于UIElement实例的content,wpf图形渲染就可以将它显示为图形,对于非UIElement实例的content,就直接执行简单的tostring即可。而对于一个UIElement实例是通过OnRender来图形化的。

唯一直接继承与UIElement的类是FrameworkElement。

我们以image为例来说明一些。

public MyWindow()

{

Uri uri = new Uri("http://www.mjjq.com/blog/photos/Image/mjjq-photos-903.jpg");

BitmapImage bi = new BitmapImage(uri);

Image img = new Image();

img.Source = bi;

Content = img;

}

显示一个图片分为以下几步:

1:创建一个Uri对象,表示一个图片在网络上的地址。

2:用这个Uri对象构造一个BitmapImage对象。构造函数会把这个图像载入内存。

Uri uri = new Uri("D:\\mjjq-photos-903.jpg");可以加载本地图片。

BitmapImage bi = new BitmapImage(uri);这个过程也可以如下处理。

BitmapImage bi = new BitmapImage();

bi.BeginInit();

bi.UriSource = uri;

bi.EndInit();

由此可以看出在wpf中所有的控件都具有很多个属性,使我们可以轻易的将一个实例赋给这个属性。

关于Image类来说,他也有很多的属性,用来控制一个图片显示出来的效果:

//调整内容,填满整个目标区域

img.Stretch = Stretch.Fill;

//最大限度的适合目标区域,但是要保持纵横比

img.Stretch = Stretch.Uniform;

//保持纵横比,并且填满整个目标区域,超出区域的部分将会被裁掉

img.Stretch = Stretch.UniformToFill;

//以图片的原始大小显示

img.Stretch = Stretch.None;

当Stretch没有设定为Stretch.None,你就可以设定StretchDirection属性,他有三个设定项 img.StretchDirection = StretchDirection.DownOnly;//图像不可以大于原始尺寸

img.StretchDirection = StretchDirection.UpOnly;//图像不可以小于原始尺寸

img.StretchDirection = StretchDirection.Both;//图像的大小和原始尺寸不关联

而且这个图像的位置还可以在客户区进行移动:

img.HorizontalAlignment = HorizontalAlignment.Right;

img.VerticalAlignment = VerticalAlignment.Top;设置这个图像显示在右上角。

例子:

public MyWindow()

{

LinearGradientBrush bl = new LinearGradientBrush(Colors.Red, Colors.Blue, new Point(0, 0), new Point(1, 1));

Uri uri = new Uri("D:\\mjjq-photos-903.jpg");

BitmapImage bi = new BitmapImage();

bi.BeginInit();

bi.UriSource = uri;

bi.EndInit();

Image img = new Image();

img.Source = bi;

Height =1400;

Width = 1200;

//调整内容,填满整个目标区域

img.Stretch = Stretch.Fill;

//添加一个背景画刷

Background = bl;

img.StretchDirection = StretchDirection.DownOnly;

img.HorizontalAlignment = HorizontalAlignment.Right;

img.VerticalAlignment = VerticalAlignment.Top;

//设置透明度

img.Opacity = 0.5;

Content = img;

}

Image用于显示一个点阵图像,而shape则用来显示简单的二维矢量图。

以上这些类是存在于System.Windows.Shapes。

public MyWindow()

{

Title = "Sharp of ellipse";

Ellipse elips = new Ellipse();

elips.StrokeThickness = 24;//椭圆边线的宽度

elips.Width = 300;

elips.Height = 200;//根据这两个大小,来确定椭圆的形状。

elips.Stroke = new LinearGradientBrush(Colors.Red, Colors.Blue, new Point(0, 0), new Point(1, 1));//椭圆的边线使用的画刷。

Content = elips;

}

当然我们可以定义这个椭圆在客户区内的位置:

elips.HorizontalAlignment = HorizontalAlignment.Right;

elips.VerticalAlignment = VerticalAlignment.Bottom;右下角显示。

如果你需要显示一个富文本,那么之前的那种将文字内容直接赋予Content就不太合适了,因为他只能整体的添加格式。你需要用到 TextBlock。

public MyWindow()

{

Title = "Sharp of TextBlock";

TextBlock txt = new TextBlock();

txt.FontSize = 32;

txt.Inlines.Add("This is some");

txt.Inlines.Add(new Italic(new Run("italic")));

txt.Inlines.Add("this is some");

txt.Inlines.Add(new Bold(new Run("Bold")));

txt.Inlines.Add("this is some");

txt.Inlines.Add(new Bold(new Italic(new Run("Bold and Italic"))));

txt.TextWrapping = TextWrapping.Wrap;

Content = txt;

}

说明:

1:对于以前的我们直接将一个字符串的值赋予content,其实window的父类ContentContorl还是会先创建一个TextBlock对象,然后把字符串的值赋予这个对象,最后将这个对象赋给Content。

2:TextBlock要显示的对象都是放在Inlines属性里面,这里面都是Inline对象。属于System.Windows.Documents空间。

System..::.Object
System.Windows.Threading..::.DispatcherObject
System.Windows..::.DependencyObject
System.Windows..::.ContentElement
System.Windows..::.FrameworkContentElement
System.Windows.Documents..::.TextElement
System.Windows.Documents..::.Inline
System.Windows.Documents..::.AnchoredBlock
System.Windows.Documents..::.Span
System.Windows.Documents..::.InlineUIContainer
System.Windows.Documents..::.LineBreak
System.Windows.Documents..::.Run继承结构如上图。可以看出Inline是继承与ContentElement。而ContentElement没有OnRender方法,所有需要通过UIElement对象来将它的内容显示出来。更加明确的说Bold和Italic无法绘制自己,要通过TextBlock才能绘制出来。

InlineCollections 只允许追加TextElementType、string\Uielement的类型。

所以一般追加TextElementType都是追加一个inline对象的实例。

对于添加的每个对象都可以有自己的事件响应:

public MyWindow()

{

Title = "Sharp of TextBlock";

TextBlock txt = new TextBlock();

txt.FontSize = 32;

txt.HorizontalAlignment = HorizontalAlignment.Center;

txt.VerticalAlignment = VerticalAlignment.Center;

Content = txt;

Foreground = Brushes.Blue;

String str = "To be or not to be is a question!";

string[] spelistr = str.Split(' ');

foreach (string tstr in spelistr)

{

Run run = new Run(tstr);

run.MouseDown += new MouseButtonEventHandler(run_MouseDown);

txt.Inlines.Add(run);

txt.Inlines.Add(" ");

}

}

void run_MouseDown(object sender, MouseButtonEventArgs e)

{

Run run = sender as Run;

if (e.ChangedButton == MouseButton.Left)

{

run.FontStyle = run.FontStyle == FontStyles.Italic ? FontStyles.Normal : FontStyles.Italic;

}

else if (e.ChangedButton == MouseButton.Right)

{

run.FontStyle = run.FontStyle == FontStyles.Oblique ? FontStyles.Normal : FontStyles.Oblique;

}

// throw new NotImplementedException();

}

可以看到每一个run对象是一个独立的对象,有自己的格式和事件响应,但是他要显示出来就需要通过UIElement对象的绘制功能了。

using System;

using System.Windows;

using System.Windows.Media;

namespace WPFDemo

{

class SimlpEllipse:FrameworkElement

{

protected override void OnRender(DrawingContext drawingContext)

{

drawingContext.DrawEllipse(Brushes.Blue,new Pen(Brushes.Red,24),

new Point(RenderSize.Width/2,RenderSize.Height/2) ,

RenderSize.Width/2,RenderSize.Height/2);

}

}

}

自定义一个椭圆类,继承与FrameworkElement,所以他是有OnRender方法的,我们通过重写这个方法,来让这个对象在界面上显示出一个椭圆。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: