Silverlight具有打印功能,可以选择性地打印页面上的对象,下面给出的实例项目展示了Silverlight的“基本打印功能”(在项目的Page1.xaml中),MainPage.xaml的页面安排了1个链接可以跳转到Page1.xaml。下面分别介绍。
1. 基本打印功能界面
图4-19是基本打印功能的界面。
图4-19给出了Page1.xaml中打印页面图片和文本的2个设计,图片Image的控件名为image1,其中的按钮控件名为BtprintImage,右侧文本框控件TextBlock的名为textblock1,其中的按钮控件名为BtprintText。它们都分别组合在Grid布局控件中。设计语句不复杂。
Silverlight的打印依靠PrintDocument类,它提供了打印对话框、打印操作和打印完成处理等功能。下面是初始化语句:
首先要为使用PrintDocument类添加命名空间引用:
using System.Windows.Printing;
图4-19
- 程序开始的初始化:
- //定义图片和文本打印变量
- PrintDocument printImage,printText;
- public Page1()
- {
- InitializeComponent();
- //图片打印对象
- printImage = new PrintDocument();
- //图片打印事件处理
- printImage.PrintPage += new
- EventHandler<PrintPageEventArgs>(printImage_PrintPage);
- //文本打印对象
- printText = new PrintDocument();
- //文本打印事件处理
- printText.PrintPage += new
- EventHandler<PrintPageEventArgs>(printText_PrintPage);
- }
- //点击图片打印按钮
- private void BTprintImage_Click(object sender,
- System.Windows.RoutedEventArgs e)
- {
- //启动打印图片,出现打印对话框
- printImage.Print("iamge1");
- }
- //确认打印后开始打印
- void printImage_PrintPage(object sender, PrintPageEventArgs e)
- {
- //确认打印,打印对象
- e.PageVisual = image1;
- }
- 当启动打印时会出现和Windows下的打印对话框,如图4-20。
图4-20
在图4-20中可以选择打印机,确定是否打印。如果打印就会开始打印。
文本框打印复杂一点,本例中首先将文本框textblock1的文本添加到Stackpanel布局控件中(也可以是其它容器控件,如Grid),然后再启动打印,后面的过程和打印图片一样。
- /定义布局控件变量
- StackPanel printarea;
- private void BTprintText_Click(object sender,
- System.Windows.RoutedEventArgs e)
- {
- //打印文本的的字符长度,压缩尾部空格
- int length=this.textblock1.Text.TrimEnd().Length;
- //打印宽度设置
- int w=18;
- //布局对象,StackPanel默认纵向排列添加的对象
- printarea=new StackPanel();
- //获取文本,直到文本尾
- for (int i=0;i<=length;ii=i+w)
- {
- //如果文本剩余长度不小于设定宽度
- if (this.textblock1.Text.TrimEnd().Substring(i).Length>=w){
- //布局控件添加文本对象,按设置宽度截取文本,设置字体字号
- printarea.Children.Add(new
- TextBlock(){Text=this.textblock1.Text.Trim().
- Substring(i,w),
- FontFamily=
- new System.Windows.Media.FontFamily("Arial"),FontSize=12});
- }else {
- //否则一直截取到文本尾
- printarea.Children.Add(new
- TextBlock(){Text=
- this.textblock1.Text.TrimEnd().Substring(i),
- FontFamily=
- new System.Windows.Media.FontFamily("Arial"),FontSize=12});
- }
- }
- //启动打印
- printText.Print("文本打印");
- }
- //确认打印后开始打印
- void printText_PrintPage(object sender, PrintPageEventArgs e)
- {
- e.PageVisual =printarea;
- }
2. 具有“打印预览和排版”效果的打印设计
图4-21 具有打印预览排版效果的设计界面
图4-22 打印预览窗口
预览窗口有1个打印区,大小类似A4版面。其中有如下控件:
字体选择使用组合框ComboBox控件(名为combobox1),用于选择字体,本例只采用了部分字体。字号选择也采用ComboBox控件(名为combobox2)用于选择字号,本例只采用了部分字号,最大到24。3个按钮“预览”(名为view)、“打印”(名为print)和“关闭”(名为exit)。打印区实际上是1个Canvas布局控件(名为canvasprint),其Top位于上述控件的下边缘。
打印区中有1个打印对象(有背景色),是Grid控件(名为printarea),打印对象位于canvasprint中,使用Canvas控件方便打印对象的位置设置。图2-55中已经添加了富文本控件RichTextBox(如果打印图片添加的是Image控件),周边有4个由Rectangle控件组成的红色移动标,从上、左、下、右依次分别命名为rec1、rec2、rec3和rec4。其中拖动rec1可以移动打印对象在打印区的位置;拖动rec2可以向左增大或缩小打印对象的宽度;拖动rec3可以增加或缩小打印对象的高度;拖动rec4可以向右增大或缩小打印对象的宽度。这4个移动标可以实现打印对象在打印区的自由布局。另外,对于文本来说,由于使用RichTextBox,当移动标移动时RichTextBox的宽度、高度也跟随变化,其中的文本自动重新排列。移动图片的过程比文本要简单一些。
打印时,4个移动标、打印对象的背景和RichTextBox的边框也会被打印出来,所以安排了相关设计,打印时隐藏这些部分,打印后再显示。进入预览窗口后首先要点击“预览”按钮才能看到预览效果,当改变字体、字号、取消打印时都需要重新点击“预览”按钮,起到刷新作用。
下面是程序。
在MainPage.xaml.cs开始添加了命名空间引用:
using System.Windows.Printing;//for PrintDocument
using System.Windows.Media.Imaging;//for BitmapImage
程序初始化部分:
- //设置打印变量
- PrintDocument printer;
- //字符串变量prn用于区分图片打印和文本打印
- string prn;
- //打印对象控件尺寸和坐标变量设置,分别对应宽、高、左边距、上边距
- double w,h,left,top;
- double x,y; //记录打印对象变化坐标,动态变化值
- //打印对象Grid的背景色,橘红色
- SolidColorBrush scb=new SolidColorBrush(Colors.Orange);
- string ztselected; //记录选择的字体
- int zhselected; //记录选择的字号
- //定义富文本控件,用于动态获取打印文本的字符串
- RichTextBox newnewtb=new RichTextBox();
- WriteableBitmap wb; // WriteableBitmap类用于截取视频“快照”
- public MainPage()
- {
- InitializeComponent();
- this.ChildView.HasCloseButton=false; //不需要子窗口的关闭按钮
- //子窗口标题栏设置,使用定义StackPanel控件设置布局
- StackPanel titlepanel=new StackPanel();
- //StackPanel控件水平排列对象
- titlepanel.Orientation=Orientation.Horizontal;
- //设置鼠标悬浮在标题栏时的形状
- titlepanel.Cursor=Cursors.Hand;
- //定义1个图标,用于标题栏
- Image im=new Image();
- im.Width=20;
- im.Height=20;
- im.Source=new BitmapImage(new Uri("sucai/icon16.png",
- UriKind.Relative));
- titlepanel.Children.Add(im); //标题栏首先添加图标
- TextBlock text=new TextBlock();//标题栏添加文本框,设置标题提示
- text.Text=" 打印预览……";
- text.Width=this.ChildView.Width;
- text.FontSize=12;
- titlepanel.Children.Add(text);
- this.ChildView.Title=titlepanel; //子窗口标题栏设置
- //打印预览子窗口设置,默认字体Arial,默认字号12
- // combobox1的第1个选择项(序号0)是Arial
- this.combobox1.SelectedIndex=0;
- // combobox2的第2个选择项(序号1)是12
- this.combobox2.SelectedIndex=1;
- //打印对象背景设置,即Grid控件的背景
- this.printarea.Background=scb;
- w=this.printarea.Width; //记录打印对象的初始参数
- h=this.printarea.Height;
- //7是移动标Rectangle边长的一半,保证移动标中心和打印对象的边重合
- left=Canvas.GetLeft(this.printarea)-7;
- top=Canvas.GetTop(this.printarea)-7;
- //设置移动标的位置,分布在打印对象4个边的中间位置
- SetRecPosition();
- printer = new PrintDocument();//设置打印对象
- //设置打印开始事件
- printer.PrintPage +=
- new EventHandler<PrintPageEventArgs>(printer_PrintPage);
- //设置打印结束事件
- printer.EndPrint+=
- new EventHandler<EndPrintEventArgs>(printer_EndPrintPage);
- }
- //设置移动标位置
- private void SetRecPosition(){
- Canvas.SetLeft(rec1,left+w/2);
- Canvas.SetTop(rec1,top);
- Canvas.SetLeft(rec2,left);
- Canvas.SetTop(rec2,top+h/2);
- Canvas.SetLeft(rec3,left+w/2);
- Canvas.SetTop(rec3,top+h);
- Canvas.SetLeft(rec4,left+w);
- Canvas.SetTop(rec4,top+h/2);
- }
- //点击图片打印预览按钮
- private void BTprintImage_Click(object sender,
- System.Windows.RoutedEventArgs e)
- {
- prn="image";//记录打印对象
- //子窗口弹出(默认隐藏)
- this.ChildView.Visibility=Visibility.Visible;
- //打印对象清空(请Grid中的子对象)
- this.printarea.Children.Clear();
- }
- //点击文本打印预览
- private void BTprintText_Click(object sender,
- System.Windows.RoutedEventArgs e)
- {
- prn="text";
- this.ChildView.Visibility=Visibility.Visible;
- this.printarea.Children.Clear();
- }
- //点击截取视频图片打印预览
- private void BTprintVideo_Click(object sender,
- System.Windows.RoutedEventArgs e)
- {
- //截取视频“快照”
- wb = new WriteableBitmap(me, null);//快照截图
- prn="video";
- this.ChildView.Visibility=Visibility.Visible;
- this.printarea.Children.Clear();
- }
- //预览子窗口程序,预览判断和预览
- string subs;
- private void view_Click(object sender, System.Windows.RoutedEventArgs e)
- {
- this.printarea.Children.Clear();
- //恢复移动标显示
- this.rec1.Visibility=Visibility.Visible;
- this.rec2.Visibility=Visibility.Visible;
- this.rec3.Visibility=Visibility.Visible;
- this.rec4.Visibility=Visibility.Visible;
- //富文本框滚动条设置
- newtb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
- //富文本框边框宽度设置
- newnewtb.BorderThickness=new Thickness(1,1,1,1);
- //打印对象背景颜色设置
- this.printarea.Background=scb;
- switch (prn){
- case "image":
- //打印图片,添加Image控件,获取图片源
- this.printarea.Children.Add(new Image(){Source=new BitmapImage(new Uri("sucai/im2.jpg", UriKind.Relative)),
- StretchStretch=Stretch.Uniform});
- break;
- case "video":
- //打印视频截图,添加Image控件,获取图片源
- this.printarea.Children.Add(new Image(){Source=wb,
- StretchStretch=Stretch.Uniform});
- break;
- case "text":
- //获取文本字号
- zhselected=
- Convert.ToInt32(this.combobox2.SelectionBoxItem.ToString());
- //获取文本字体字体
- ztselected=this.combobox1.SelectionBoxItem.ToString();
- newtb.Blocks.Clear();//富文本内部清空
- //富文本尺寸同打印对象(Grid)
- newtb.Width=this.printarea.Width;
- newtb.Height=this.printarea.Height;
- Run run1 = new Run();//定义富文本框中段落的子元素
- run1.FontSize=zhselected;
- run1.FontFamily=
- new System.Windows.Media.FontFamily(ztselected);
- run1.Text=this.textblock1.Text;
- //定义富文本框的段落,段落由元素组成
- Paragraph paragraph = new Paragraph();
- //段落添加子元素
- paragraph.Inlines.Add(run1);
- //Blocks是富文本框的内容属性,是段落Paragraph的集合
- newtb.Blocks.Add(paragraph);
- //富文本框进入打印对象
- this.printarea.Children.Add(newtb);
- break;
- }
- }
- //启动打印
- private void print_Click(object sender, System.Windows.RoutedEventArgs e)
- {
- //显示打印选择对话框,选择打印机,确认打印,隐藏移动标、边框、取消背景颜色
- this.rec1.Visibility=Visibility.Collapsed;
- this.rec2.Visibility=Visibility.Collapsed;
- this.rec3.Visibility=Visibility.Collapsed;
- this.rec4.Visibility=Visibility.Collapsed;
- newtb.VerticalScrollBarVisibility = ScrollBarVisibility.Hidden;
- newnewtb.BorderThickness=new Thickness(0,0,0,0);
- this.printarea.Background=null;
- //启动打印,出现打印对话框,选择打印机,确认是否打印
- printer.Print("打印……");
- }
- //确认打印后开始打印
- void printer_PrintPage(object sender, PrintPageEventArgs e)
- {
- e.PageVisual =canvasprint;
- }
- //结束打印(送出打印最后1页信息)
- void printer_EndPrintPage(object sender, EndPrintEventArgs e)
- {
- //恢复显示
- this.rec1.Visibility=Visibility.Visible;
- this.rec2.Visibility=Visibility.Visible;
- this.rec3.Visibility=Visibility.Visible;
- this.rec4.Visibility=Visibility.Visible;
- newtb.VerticalScrollBarVisibility = ScrollBarVisibility.Auto;
- newnewtb.BorderThickness=new Thickness(1,1,1,1);
- this.printarea.Background=scb;
- }
- //退出预览窗口
- private void exit_Click(object sender, System.Windows.RoutedEventArgs e)
- {
- this.ChildView.Visibility=Visibility.Collapsed;
- }
- //链接到Page1
- private void tb1_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- this.Content=new Page1();
- }
- //移动标程序设计,记忆鼠标移动时的位置
- Point curpos;
- bool mousemoving=false; //是否拖动标志设置
- //鼠标选中rec1
- private void rec1_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- curpos=e.GetPosition(null); //获取鼠标当前坐标
- mousemoving=true; //设置标志,允许拖动
- this.rec1.CaptureMouse();//鼠标捕获允许
- }
- //移动标rec1移动,在打印区移动打印对象位置
- private void rec1_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
- {
- if (mousemoving){
- //计算鼠标X方向增加值
- double addX=e.GetPosition(null).X-curpos.X;
- //计算鼠标Y方向增加值
- double addY=e.GetPosition(null).Y-curpos.Y;
- //设置打印对象新位置坐标
- Canvas.SetLeft(printarea,addX+Canvas.GetLeft(printarea));
- Canvas.SetTop(printarea,addY+Canvas.GetTop(printarea));
- //计算边距,重新设置移动标的位置,保证移动标一直处于打印对象周边中央
- left=Canvas.GetLeft(this.printarea)-7;
- top=Canvas.GetTop(this.printarea)-7;
- SetRecPosition();
- curpos=e.GetPosition(null);
- }
- }
- //移动标rec1停止
- private void rec1_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- mousemoving=false; //拖动禁止
- this.rec1.ReleaseMouseCapture();//停止鼠标捕获
- }
- //鼠标选中rec2
- private void rec2_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- curpos=e.GetPosition(null);
- y=Canvas.GetTop(printarea);
- top=y-7;
- mousemoving=true;
- this.rec2.CaptureMouse();
- }
- //移动标rec2移动改变打印区宽度
- private void rec2_MouseMove(object sender,
- System.Windows.Input.MouseEventArgs e)
- {
- if (mousemoving){
- //计算鼠标X方向增加值
- double addX=e.GetPosition(null).X-curpos.X;
- //设置打印对象新位置坐标
- Canvas.SetLeft(printarea,addX+Canvas.GetLeft(printarea));
- Canvas.SetTop(printarea,y); //y上边距不变化
- //打印对象宽度变化
- thisthis.printarea.Width=this.printarea.Width-addX;
- this.printarea.Background=scb;
- left=Canvas.GetLeft(this.printarea)-7;
- w=this.printarea.Width;
- SetRecPosition();
- newtb.Width=w; //富文本框宽度变化
- curpos=e.GetPosition(null);
- }
- }
- //移动标rec2移动停止
- private void rec2_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- mousemoving=false;
- this.rec2.ReleaseMouseCapture();
- }
- //鼠标选中rec4
- private void rec4_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- curpos=e.GetPosition(null);
- y=Canvas.GetTop(printarea);
- x=Canvas.GetLeft(this.printarea);
- mousemoving=true;
- this.rec4.CaptureMouse();
- }
- //移动标rec4移动改变打印区宽度
- private void rec4_MouseMove(object sender,
- System.Windows.Input.MouseEventArgs e)
- {
- if (mousemoving){
- double addX=e.GetPosition(null).X-curpos.X;
- Canvas.SetLeft(printarea,x);//对象新位置坐标
- Canvas.SetTop(printarea,y);
- thisthis.printarea.Width=this.printarea.Width+addX;
- this.printarea.Background=scb;
- left=x-7;
- top=y-7;
- w=this.printarea.Width;
- SetRecPosition();
- newtb.Width=w;
- curpos=e.GetPosition(null);
- }
- }
- //rec4停止拖动
- private void rec4_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- mousemoving=false;
- this.rec4.ReleaseMouseCapture();
- }
- //鼠标选中rec3
- private void rec3_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- curpos=e.GetPosition(null);
- x=Canvas.GetLeft(printarea);
- y=Canvas.GetTop(printarea);
- top=y-7;
- w=this.printarea.Width;
- mousemoving=true;//允许拖动
- this.rec3.CaptureMouse();//鼠标捕获允许
- }
- //移动标rec3移动改变打印区高度
- private void rec3_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
- {
- if (mousemoving){
- double addY=e.GetPosition(null).Y-curpos.Y;
- Canvas.SetLeft(printarea,x); //位置没有变化
- Canvas.SetTop(printarea,y);
- thisthis.printarea.Height=this.printarea.Height+addY; //高度变化
- this.printarea.Background=scb;
- left=Canvas.GetLeft(this.printarea)-7;
- h=this.printarea.Height;
- SetRecPosition();
- newtb.Height=h; //富文本框高度变化
- curpos=e.GetPosition(null);
- }
- }
- //左下角移动标rec3移动停止
- private void rec3_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
- {
- mousemoving=false;
- this.rec3.ReleaseMouseCapture();
- }
- //视频播放结束再启动播放
- private void me_MediaEnded(object sender, System.Windows.RoutedEventArgs e)
- {
- this.me.Stop();
- this.me.Play();
- }
具有一定排版效果的打印设计界面如图4-21所示,在MainPage.xaml中,和图4-19相比,仅仅是图片和文本“打印”按钮的标题改为“进入预览”,控件的名称同上,文本的长度长一点,多了1个视频截图打印,视频控件MediaElement的名为me,其中的按钮名为BTprintVideo。这里设计了预览窗口,是1个ChildWindow(名为ChildView)子窗口,预览窗口的界面如图4-22所示。