稳扎稳打Silverlight(48) - 4.0其它之打印, 动态绑定, 增强的导航系统, 杂七杂八
稳扎稳打Silverlight(48) - 4.0其它之打印, 动态绑定, 增强的导航系统, 杂七杂八
作者:webabcd
介绍
Silverlight 4.0 其它:
- 打印 - Silverlight 4.0 中新增的对打印的支持
- 动态绑定 - 新增的 C# 4.0 的特性及其应用
- 增强的导航系统
- 杂七杂八
在线DEMO
http://www.cnblogs.com/webabcd/archive/2010/08/09/1795417.html
示例
1、演示在 Silverlight 4.0 中如何做打印操作,以及如何打印多页
Print.xaml
代码
<navigation:Page x:Class="Silverlight40.Other.Print"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="Print Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<TextBlock Name="lblMsg" />
<Button Name="btnPrint" Content="打印图片" Click="btnPrint_Click" />
<Canvas Name="canvas">
<Image Name="image" Width="300" Height="4000" Source="/Resource/Logo.jpg" Stretch="Fill" />
</Canvas>
</StackPanel>
</Grid>
</navigation:Page>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="Print Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<TextBlock Name="lblMsg" />
<Button Name="btnPrint" Content="打印图片" Click="btnPrint_Click" />
<Canvas Name="canvas">
<Image Name="image" Width="300" Height="4000" Source="/Resource/Logo.jpg" Stretch="Fill" />
</Canvas>
</StackPanel>
</Grid>
</navigation:Page>
Print.xaml.cs
代码
/*
* 演示 Silverlight 4.0 中新增的对打印的支持
* PrintDocument - 用于提供打印功能的类
* PrintDocument.PrintedPageCount - 已经被打印的页数
* PrintDocument.Print(string documentName) - 弹出打印对话框。需要指定的参数为“在打印队列中需要显示的文档名称”
* PrintDocument.BeginPrint - 调用 Print() 方法并且按了打印对话框中的打印按钮之后所触发的事件,在 PrintPage 事件之前发生
* PrintDocument.EndPrint - 打印结束(包括打印被取消)后所触发的事件
* PrintDocument.PrintPage - 每打印一页之前所触发的事件
* PrintPageEventArgs - PrintPage 事件的事件参数
* PrintPageEventArgs.PageVisual - 需要被打印的 UIElement
* PrintPageEventArgs.PrintableArea - 可打印的区域大小(Size 类型,其包括 Width 属性和 Height 属性和 IsEmpty 属性)
* PrintPageEventArgs.PageMargins - 获取当前打印页的页边距(Thickness 类型,其包括 Left 属性和 Top 属性和 Right 属性和 Bottom 属性)
* PrintPageEventArgs.HasMorePages - 设置是否还有更多页需要打印(如果设置为 true,则会继续出触发 PrintPage 事件)
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Windows.Printing;
namespace Silverlight40.Other
{
public partial class Print : Page
{
PrintDocument _printDocument;
double _offsetY = 0d;
double _totalHeight = 0d;
public Print()
{
InitializeComponent();
}
private void btnPrint_Click(object sender, RoutedEventArgs e)
{
_totalHeight = image.ActualHeight;
_printDocument.Print("打印队列中显示的文档名称");
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_printDocument = new PrintDocument();
_printDocument.PrintPage += new EventHandler<PrintPageEventArgs>(_printDocument_PrintPage);
_printDocument.BeginPrint += new EventHandler<BeginPrintEventArgs>(_printDocument_BeginPrint);
_printDocument.EndPrint += new EventHandler<EndPrintEventArgs>(_printDocument_EndPrint);
}
void _printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
e.PageVisual = canvas;
// 如果需要打印的 UIElement 超过了 PrintableArea,则超过的部分在打印的时候都会被剪裁。所以如果需要打印多页的话,必须对被打印的 UIElement 所显示的内容做手工调整,使当前需要被打印的内容出现在 PrintableArea 中
Canvas.SetTop(image, -_offsetY);
_offsetY += e.PrintableArea.Height;
e.HasMorePages = _offsetY <= _totalHeight;
lblMsg.Text += "正在打印:第" + (_printDocument.PrintedPageCount + 1).ToString() + "页\n";
lblMsg.Text += string.Format("当前打印的页边距:左{0},上{1},右{2},下{3}\n", e.PageMargins.Left, e.PageMargins.Top, e.PageMargins.Right, e.PageMargins.Bottom);
lblMsg.Text += "可打印区域的宽和高:" + e.PrintableArea.Width.ToString() + "×" + e.PrintableArea.Height.ToString() + "\n";
}
void _printDocument_BeginPrint(object sender, BeginPrintEventArgs e)
{
lblMsg.Text += "开始打印\n";
}
void _printDocument_EndPrint(object sender, EndPrintEventArgs e)
{
Canvas.SetTop(image, 0);
// EndPrintEventArgs.Error - 如果在打印过程中发生异常,则返回该异常
if (e.Error == null)
lblMsg.Text += "打印结束\n";
else
lblMsg.Text += "打印出错:" + e.Error.ToString() + "\n";
}
}
}
* 演示 Silverlight 4.0 中新增的对打印的支持
* PrintDocument - 用于提供打印功能的类
* PrintDocument.PrintedPageCount - 已经被打印的页数
* PrintDocument.Print(string documentName) - 弹出打印对话框。需要指定的参数为“在打印队列中需要显示的文档名称”
* PrintDocument.BeginPrint - 调用 Print() 方法并且按了打印对话框中的打印按钮之后所触发的事件,在 PrintPage 事件之前发生
* PrintDocument.EndPrint - 打印结束(包括打印被取消)后所触发的事件
* PrintDocument.PrintPage - 每打印一页之前所触发的事件
* PrintPageEventArgs - PrintPage 事件的事件参数
* PrintPageEventArgs.PageVisual - 需要被打印的 UIElement
* PrintPageEventArgs.PrintableArea - 可打印的区域大小(Size 类型,其包括 Width 属性和 Height 属性和 IsEmpty 属性)
* PrintPageEventArgs.PageMargins - 获取当前打印页的页边距(Thickness 类型,其包括 Left 属性和 Top 属性和 Right 属性和 Bottom 属性)
* PrintPageEventArgs.HasMorePages - 设置是否还有更多页需要打印(如果设置为 true,则会继续出触发 PrintPage 事件)
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Windows.Printing;
namespace Silverlight40.Other
{
public partial class Print : Page
{
PrintDocument _printDocument;
double _offsetY = 0d;
double _totalHeight = 0d;
public Print()
{
InitializeComponent();
}
private void btnPrint_Click(object sender, RoutedEventArgs e)
{
_totalHeight = image.ActualHeight;
_printDocument.Print("打印队列中显示的文档名称");
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
_printDocument = new PrintDocument();
_printDocument.PrintPage += new EventHandler<PrintPageEventArgs>(_printDocument_PrintPage);
_printDocument.BeginPrint += new EventHandler<BeginPrintEventArgs>(_printDocument_BeginPrint);
_printDocument.EndPrint += new EventHandler<EndPrintEventArgs>(_printDocument_EndPrint);
}
void _printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
e.PageVisual = canvas;
// 如果需要打印的 UIElement 超过了 PrintableArea,则超过的部分在打印的时候都会被剪裁。所以如果需要打印多页的话,必须对被打印的 UIElement 所显示的内容做手工调整,使当前需要被打印的内容出现在 PrintableArea 中
Canvas.SetTop(image, -_offsetY);
_offsetY += e.PrintableArea.Height;
e.HasMorePages = _offsetY <= _totalHeight;
lblMsg.Text += "正在打印:第" + (_printDocument.PrintedPageCount + 1).ToString() + "页\n";
lblMsg.Text += string.Format("当前打印的页边距:左{0},上{1},右{2},下{3}\n", e.PageMargins.Left, e.PageMargins.Top, e.PageMargins.Right, e.PageMargins.Bottom);
lblMsg.Text += "可打印区域的宽和高:" + e.PrintableArea.Width.ToString() + "×" + e.PrintableArea.Height.ToString() + "\n";
}
void _printDocument_BeginPrint(object sender, BeginPrintEventArgs e)
{
lblMsg.Text += "开始打印\n";
}
void _printDocument_EndPrint(object sender, EndPrintEventArgs e)
{
Canvas.SetTop(image, 0);
// EndPrintEventArgs.Error - 如果在打印过程中发生异常,则返回该异常
if (e.Error == null)
lblMsg.Text += "打印结束\n";
else
lblMsg.Text += "打印出错:" + e.Error.ToString() + "\n";
}
}
}
2、演示动态绑定的应用
DynamicBinding.xaml.cs
代码
/*
* 演示如何通过类型为 dynamic 的对象动态绑定到 HTML DOM 元素以及如何通过动态绑定调用 JavaScript
* 使用 dynamic 之前,要先引用 Microsoft.CSharp.dll 程序集
*
* 在 Silverlight40TestPage.html 页上运行程序,以查看本 Demo 的演示效果
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Windows.Browser;
namespace Silverlight40.Other
{
public partial class DynamicBinding : Page
{
public DynamicBinding()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DOMDemo();
JavaScriptDemo();
}
private void DOMDemo()
{
// 声明 HTML DOM 中的 document 为一个 dynamic 类型的对象。也就是说可以把这里的 document 对象看作是 HTML DOM Document 对象来编程
// HtmlDocument继承自HtmlObject,HtmlObject继承自ScriptObject,ScriptObject 实现了 IDynamicMetaObjectProvider 接口,所以支持动态绑定
dynamic document = HtmlPage.Document;
// 获取页面上的一个名为“hello”的 div 中的内容,只需要用 HTML DOM 的编程方式即可
string s = document.getElementById("hello").innerHTML;
MessageBox.Show(s);
}
private void JavaScriptDemo()
{
// 获取浏览器内的 window 对象
dynamic window = HtmlPage.Window;
// 调用 JavaScript
window.alert("Hello: webabcd");
}
}
}
* 演示如何通过类型为 dynamic 的对象动态绑定到 HTML DOM 元素以及如何通过动态绑定调用 JavaScript
* 使用 dynamic 之前,要先引用 Microsoft.CSharp.dll 程序集
*
* 在 Silverlight40TestPage.html 页上运行程序,以查看本 Demo 的演示效果
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
using System.Windows.Browser;
namespace Silverlight40.Other
{
public partial class DynamicBinding : Page
{
public DynamicBinding()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DOMDemo();
JavaScriptDemo();
}
private void DOMDemo()
{
// 声明 HTML DOM 中的 document 为一个 dynamic 类型的对象。也就是说可以把这里的 document 对象看作是 HTML DOM Document 对象来编程
// HtmlDocument继承自HtmlObject,HtmlObject继承自ScriptObject,ScriptObject 实现了 IDynamicMetaObjectProvider 接口,所以支持动态绑定
dynamic document = HtmlPage.Document;
// 获取页面上的一个名为“hello”的 div 中的内容,只需要用 HTML DOM 的编程方式即可
string s = document.getElementById("hello").innerHTML;
MessageBox.Show(s);
}
private void JavaScriptDemo()
{
// 获取浏览器内的 window 对象
dynamic window = HtmlPage.Window;
// 调用 JavaScript
window.alert("Hello: webabcd");
}
}
}
相关的 DOM 部分
Silverlight40TestPage.html
<div style="font-size: 12px; text-align: left" id="hello">
I am a div
</div>
I am a div
</div>
3、介绍导航系统的增强
NavigationEnhancement.xaml
代码
<navigation:Page x:Class="Silverlight40.Other.NavigationEnhancement"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="NavigationEnhancement Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<HyperlinkButton Margin="5" NavigateUri="http://www.cnblogs.com/webabcd/archive/2009/08/10/1542663.html" TargetName="_blank" Content="Silverlight 3.0 中的导航系统的基本功能的演示" />
<TextBlock Text="Frame 和 NavigationService 新增了 Refresh() 方法" Margin="5" />
<TextBlock Margin="5">
<Run>Frame 的 ContentLoader 属性默认是 PageResourceContentLoader 类型的对象</Run>
<LineBreak />
<Run>如果需要自定义导系统,那么需要实现 INavigationContentLoader 接口,然后将 Frame 的 ContentLoader 属性设置为实现了该接口的类的实例即可</Run>
</TextBlock>
</StackPanel>
</Grid>
</navigation:Page>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
Title="NavigationEnhancement Page">
<Grid x:Name="LayoutRoot">
<StackPanel HorizontalAlignment="Left">
<HyperlinkButton Margin="5" NavigateUri="http://www.cnblogs.com/webabcd/archive/2009/08/10/1542663.html" TargetName="_blank" Content="Silverlight 3.0 中的导航系统的基本功能的演示" />
<TextBlock Text="Frame 和 NavigationService 新增了 Refresh() 方法" Margin="5" />
<TextBlock Margin="5">
<Run>Frame 的 ContentLoader 属性默认是 PageResourceContentLoader 类型的对象</Run>
<LineBreak />
<Run>如果需要自定义导系统,那么需要实现 INavigationContentLoader 接口,然后将 Frame 的 ContentLoader 属性设置为实现了该接口的类的实例即可</Run>
</TextBlock>
</StackPanel>
</Grid>
</navigation:Page>
4、杂七杂八
Summary.xaml.cs
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace Silverlight40.Other
{
public partial class Summary : Page
{
public Summary()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
IsNullOrWhiteSpaceDemo();
ConcatAndJoinDemo();
TupleDemo();
HasFlagDemo();
}
// String.IsNullOrWhiteSpace() - 判断字符串是否是 null,是否是空字符串,是否是空白字符
private void IsNullOrWhiteSpaceDemo()
{
lblMsg.Text += string.Format("null: {0}, \"\": {1}, \" \": {2}, \" \": {3}",
string.IsNullOrWhiteSpace(null).ToString(), // true
string.IsNullOrWhiteSpace("").ToString(), // true
string.IsNullOrWhiteSpace(" ").ToString(), // true
string.IsNullOrWhiteSpace(" ").ToString()); // true
lblMsg.Text += "\n";
// 运行结果:
// null: True, "": True, " ": True, " ": True
}
// String.Concat() 和 String.Join() - 增加了对 IEnumerable<T> 类型的支持
private void ConcatAndJoinDemo()
{
List<int> list = new List<int>();
for (int i = 0; i < 10; i++)
{
list.Add(i);
}
lblMsg.Text += string.Concat(list);
lblMsg.Text += " ";
lblMsg.Text += string.Join(",", list);
lblMsg.Text += "\n";
// 运行结果:
// 0123456789 0,1,2,3,4,5,6,7,8,9
}
// Tuple(元组)的 Demo
private void TupleDemo()
{
var tuple = Tuple.Create(1, "s", DateTime.Now);
lblMsg.Text += string.Format("{0}, {1}, {2}",
tuple.Item1.ToString(),
tuple.Item2.ToString(),
tuple.Item3.ToString());
lblMsg.Text += "\n";
// 运行结果:
// 1, s, 2010/8/30 8:37:12
}
// 演示对 [Flags] 枚举的支持
private void HasFlagDemo()
{
FlagsEnum e1 = FlagsEnum.B | FlagsEnum.D;
FlagsEnum e2 = FlagsEnum.All;
lblMsg.Text += string.Format("{0}, {1}, {2}",
e1.HasFlag(FlagsEnum.B).ToString(),
e1.HasFlag(FlagsEnum.D).ToString(),
e2.HasFlag(FlagsEnum.F).ToString());
lblMsg.Text += "\n";
// 运行结果:
// True, True, True
}
}
[Flags]
public enum FlagsEnum
{
A = 0,
B = 1,
C = 2,
D = 4,
E = 8,
F = 16,
All = 0 | 1 | 2 | 4 | 8 | 16
}
}
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Navigation;
namespace Silverlight40.Other
{
public partial class Summary : Page
{
public Summary()
{
InitializeComponent();
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
IsNullOrWhiteSpaceDemo();
ConcatAndJoinDemo();
TupleDemo();
HasFlagDemo();
}
// String.IsNullOrWhiteSpace() - 判断字符串是否是 null,是否是空字符串,是否是空白字符
private void IsNullOrWhiteSpaceDemo()
{
lblMsg.Text += string.Format("null: {0}, \"\": {1}, \" \": {2}, \" \": {3}",
string.IsNullOrWhiteSpace(null).ToString(), // true
string.IsNullOrWhiteSpace("").ToString(), // true
string.IsNullOrWhiteSpace(" ").ToString(), // true
string.IsNullOrWhiteSpace(" ").ToString()); // true
lblMsg.Text += "\n";
// 运行结果:
// null: True, "": True, " ": True, " ": True
}
// String.Concat() 和 String.Join() - 增加了对 IEnumerable<T> 类型的支持
private void ConcatAndJoinDemo()
{
List<int> list = new List<int>();
for (int i = 0; i < 10; i++)
{
list.Add(i);
}
lblMsg.Text += string.Concat(list);
lblMsg.Text += " ";
lblMsg.Text += string.Join(",", list);
lblMsg.Text += "\n";
// 运行结果:
// 0123456789 0,1,2,3,4,5,6,7,8,9
}
// Tuple(元组)的 Demo
private void TupleDemo()
{
var tuple = Tuple.Create(1, "s", DateTime.Now);
lblMsg.Text += string.Format("{0}, {1}, {2}",
tuple.Item1.ToString(),
tuple.Item2.ToString(),
tuple.Item3.ToString());
lblMsg.Text += "\n";
// 运行结果:
// 1, s, 2010/8/30 8:37:12
}
// 演示对 [Flags] 枚举的支持
private void HasFlagDemo()
{
FlagsEnum e1 = FlagsEnum.B | FlagsEnum.D;
FlagsEnum e2 = FlagsEnum.All;
lblMsg.Text += string.Format("{0}, {1}, {2}",
e1.HasFlag(FlagsEnum.B).ToString(),
e1.HasFlag(FlagsEnum.D).ToString(),
e2.HasFlag(FlagsEnum.F).ToString());
lblMsg.Text += "\n";
// 运行结果:
// True, True, True
}
}
[Flags]
public enum FlagsEnum
{
A = 0,
B = 1,
C = 2,
D = 4,
E = 8,
F = 16,
All = 0 | 1 | 2 | 4 | 8 | 16
}
}
OK
[源码下载]