跟着小王学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方法的,我们通过重写这个方法,来让这个对象在界面上显示出一个椭圆。
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方法的,我们通过重写这个方法,来让这个对象在界面上显示出一个椭圆。
相关文章推荐
- 跟着小王学习wpf系列之十 练习之拼图游戏
- 跟着小王学习wpf系列之十一 依赖属性一
- 跟着小王学习wpf系列之十四 单个孩子的自定义element
- 跟着小王学wpf系列一 WPF窗口
- 跟着小王学习wpf系列二 基本的wpf程序架构
- 跟着小王学习wpf系列三 颜色和画刷
- 跟着小王学wpf系列之五 Button
- 跟着小王学wpf系列之 常用控件布局控件
- 跟着小王学习wpf系列之九 Canvas
- 跟着小王学习wpf之十二 Wpf中的鼠标事件详解
- [WPF - 之一问一答系列] 如何从WPF的WebBrowser控件中获得WebResponse内容?为何WebBrowser控件的Navigated事件参数NavigationEventArgs的
- [WPF系列] 需要区分的内容
- WPF从我炫系列3---内容控件的用法
- 跟着小王学wpf之六 常用控件TextBox
- WPF学习系列009: 2.7.1 内容属性
- 跟着小王学习wpf之八 Grid
- [WPF - 之一问一答系列] 如何从WPF的WebBrowser控件中获得WebResponse内容?为何WebBrowser控件的Navigated事件参数NavigationEventArgs的WebResponse属性始终为null?
- Visual Studio 2008 开发WPF应用程序系列文章——window class 之间的继承
- WPF依赖属性,绑定通知机制系列补充说明
- 一起入门Citrix_XenDesktop7系列 四--跟着图片通过XenDesktop7交付(发布)WinXP系