博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

[索引页]
[源码下载]


稳扎稳打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>


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";
        }

    }
}



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");
        }
    }
}


相关的 DOM 部分
Silverlight40TestPage.html

    <div style="font-size: 12px; text-align: left" id="hello">
        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>



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
    }
}



OK
[源码下载]