1. Silverlight FireStarter 2010 Labs
为了方便大家学习和了解Silverlight 5新特性,微软将FireStarter大会所有的技术课程进行了汇总,发布Silverlight FireStarter Labs。大家可以通过官方网站在线观看,也可以下载到本地学习观看。
上周微软发布Visual Studio 2010 SP1 Beta版本,该版本主要解决目前反馈得到的Bugs.如果你在从事Silverlight 4和Windows Phone应用开发,推荐安装该升级包。
下边是关于SilverLight的一些应用介绍:
PrintDocument类为 Silverlight 应用程序提供打印功能。
要向 Silverlight 应用程序添加打印功能,应首先向应用程序添加 PrintDocument 对象。
若要显示打印对话框,应调用 PrintDocument的 Print() 方法。
Silverlight 中的所有对话框都必须是用户启动的。
当操作不是用户启动时,如果您试图显示打印对话框,则会导致 SecurityException。
例如,如果您试图从 Loaded 事件处理程序中显示此对话框,则出现安全异常。
//打印方法
public static void PrintForm(this UIElement uielements) { var doc = new PrintDocument();
doc.PrintPage += (s, e) => { e.PageVisual = uielements; e.HasMorePages = false; }; doc.Print(null); }
LayoutRoot中显示要打印区域
所在页面Click事件中调用打印PrintForm(LayoutRoot)。
简单页面打印
在本页面中有DataGrid数据绑定,可以根据数据加载实现分页打印
List<EmployeeModel>() employees = new List<EmployeeModel>();
//调用打印
GetPrintPage(dataPager1.PageCount, dataPager1.PageSize)
//当前数据分页中dataPager1
//当前数据页行数PageSize
//employees 当前填充DataGrid的集合
//PageCount总页码
//Pagesize 每一页页数
public void GetPrintPage(int PageCount, int Pagesize) { PrintDocument pd = new PrintDocument(); int itemindex = 0;//从第一张打印 int count = Pagesize;
//根据页码选择的数据 pd.PrintPage += (s, pe) => { StackPanel stack = new StackPanel(); while (itemindex < PageCount) { if (itemindex == PageCount- 1) { count = employees.Count - (Pagesize * itemindex); } List<EmployeeModel> itemsource = LoadNewList(employees, itemindex * Pagesize, count);
PageP mode = new PageP();//当前要打印的页面(包含数据DataGrid) int PrintPageindex = itemindex + 1; mode.MinHeight = 1058;//根据A4纸显示高度 mode.dataGrid1.ItemsSource = itemsource; stack.Children.Add(mode);
stack.Measure(new Size(pe.PrintableArea.Width, double.PositiveInfinity));
if (stack.DesiredSize.Height > pe.PrintableArea.Height | stack.Children.Count > 1) { stack.Children.Remove(mode); stack.Measure(pe.PrintableArea); pe.HasMorePages = true; break; } itemindex += 1; } pe.PageVisual = stack; }; pd.Print(null); }
// 获取指定的List集合
public static List<T> LoadNewList<T>(List<T> _source, int PIndex, int Pcounts) { List<T> newList = new List<T>();
newList.AddRange(_source.GetRange(PIndex, Pcounts)); return newList; }
附:一般打印都是A4纸;A4纸的标准是宽21cm;高29.7cm.像素为:宽588px;高:862Px;
一般除开边距margin(70,80,70,80) 余下部分就是可以是datagrid的高度,Pagesize=余下高度/(行高)。
简单数据分页打印
MainPage.xaml
<UserControl xmlns:my=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data” x:Class=”Tips.MainPage”
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“
mc:Ignorable=”d”
d:DesignHeight=”300″ d:DesignWidth=”400″ xmlns:expressionDark=”clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.ExpressionDark”>
<expressionDark:ExpressionDarkTheme>
<StackPanel Orientation=”Horizontal”>
<my:DataGrid x:Name=”dg” Width=”300″ />
<Button x:Name=”btnPrint” Click=”btnPrint_Click” Width=”60″ Height=”30″ VerticalAlignment=”Top” Content=”Print” />
</StackPanel>
</expressionDark:ExpressionDarkTheme>
</UserControl>
MainPage.xaml.cs
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Printing;
namespace Tips
{
public partial class MainPage : UserControl
{
List<string> coll = new List<string>();
private double lineHeight = 20;
private int rowIndex = 0;
private double spacetoPrint { get; set; }
private double CanvasTop { get; set; }
private Canvas PrintBody { get; set; }
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
for (int i = 0; i < 150;i++)
{
coll.Add(“Print example from http://silverlightips.net“);
}
dg.ItemsSource = coll;
}
private void btnPrint_Click(object sender, RoutedEventArgs e)
{
PrintDocument pd = new PrintDocument();
pd.PrintPage += (a, b) => {
PrintBody = new Canvas();
b.PageVisual = PrintBody;
double heightgap = 30;
spacetoPrint = b.PrintableArea.Height – (heightgap * 2);
CanvasTop = heightgap;
IterateRow(b);
};
pd.Print(“Silverligh Printing Tips”);
}
private void IterateRow(PrintPageEventArgs p)
{
if (rowIndex < coll.Count)
{
var tb = new TextBlock { Text = coll[rowIndex] };
if (lineHeight > spacetoPrint)
{
p.HasMorePages = true;
return;
}
tb.SetValue(Canvas.TopProperty, CanvasTop);
tb.SetValue(Canvas.LeftProperty, 30.00);
PrintBody.Children.Add(tb);
CanvasTop += lineHeight;
spacetoPrint -= lineHeight;
rowIndex += 1;
IterateRow(p);
}
}
}
}
关于SL打印(二)
最近在一直研究Silverlight下的数据绑定控件,发现有这样两个接口IEditableObject 和IEditableCollectionView,记录一下结论,欢迎交流指正。
本文会重点介绍在构建Silverlight自定义数据绑定控件的过程中,我们会对数据源进行操作,那么就会碰到上述两个接口,如何正确的处理它们。
IEditableObject
这个概念早在.Net 1.0的时候就提出了,但是我一直没有关注过这个东东。
What is IEditableObject?
IEditableObject is used to represent an object that has an editing mode and the ability to commit or revert changes.
UseCase:When a validation error occurs in a cell, user can back out of changes using Escape key. However if user has made changes to other columns in same row, those changes will still persists.User may wish to back out of all changes. This is where IEditableObject interface comes into play. IEditableObject is used to represent an object that has an editing mode and the ability to commit or revert changes.
Definition:
public interface IEditableObject
{ void BeginEdit(); void CancelEdit(); void EndEdit();
}
简单来说IEditableObject就是具有编辑模式,并且支持整体提交和回滚值的对象。比如一个数据行对象,你可以更改其多个列的值,在没有提交者前,都可以通过CancelEdit进行回滚。
通过一个简单的Memo模式就可以实现这个对象。
IEditableCollectionView
这个概念是在WPF3.5 SP1的时候才引入,目的是提供一个具有事务能力的集合类。
IEditableCollectionView is a new collection view that you can use to supports adding and removing new items, as well as editing items in a transactional way. It is implemented by ListCollectionView (the default view for ObservableCollection) and BindingListCollectionView (the default view for DataTable).
Definition:
public interface IEditableCollectionView
{ bool CanAddNew { get; } bool CanCancelEdit { get; } bool CanRemove { get; } object CurrentAddItem { get; } object CurrentEditItem { get; } bool IsAddingNew { get; } bool IsEditingItem { get; } NewItemPlaceholderPosition NewItemPlaceholderPosition { get; set; }
object AddNew(); void CancelEdit(); void CancelNew(); void CommitEdit(); void CommitNew(); void EditItem(object item); void Remove(object item); void RemoveAt(int index);
}
这两个接口的关系:
When the data Item implements IEditableObject, the IEditableCollectionView will call BeginEdit() when a new item is added or an existing item is opened for edit. It will call CancelEdit() when the item is cancelled and EndEdit() when the item is committed. IEditableCollectionView lets the app author handle this part of the transaction.
换句话说就是,如果IEditableCollectionView发现其Item实现了IEditableObject接口,会在它的EditItem,CommitEdit以及CancelEdit方法中调用子Item的BeginEdit,EndEdit和CancelEdit方法。
自定义数据绑定控件应该如何处理这两个接口
IEditableObject
如果数据绑定控件发现当前行绑定的对象是IEditableObject,那么在该行上如果有一个Cell进入编辑状态,并且是第一个单元格的时候,就需要调用绑定对象的BeginEdit方法。
当某一行上某一个Cell处于编辑状态的时候,Press Esc,该Cell会退出编辑状态,值也会回滚。注意这个时候不会调用IEditableObject的CancelEdit方法,这是Cell本身应该提供的行为。这个时候IsEdit为False,但是Row拥有焦点,继续Press Esc,会调用IEditableObject的CancelEdit方法,你会发现其他列的值也会回滚。
当某一行上某一个Cell处于编辑状态的时候,鼠标点击其他行,该Cell会退出编辑状态。只是会调用IEditableObject的EndEdit方法。
IEditableCollectionView
对于IEditableCollectionView来说,EditItem,CommitEdit还有CancelEdit方法分别对应着IEditableObject接口的BeginEdit,EndEdit和CancelEdit,调用时机完全一样。
数据绑定控件如果其数据源是IEditableCollectionView, 在处理BeginEdit,EndEdit和CancelEdit的时候应该直接调用CollectionView的相应方法,这个时候就不需要在处理 IEditableObject接口了,IEditableCollectionView内部会调用该接口。
只有在其数据源不是IEditableCollectionView的时候,如果Row绑定对象是IEditableObject,需要调用IEditableObject的接口实现。
这样的话,自定义数据绑定控件就可以完美支持这两个接口了。
说明:以上描述是以Silverlight DataGrid为例,自定义控件类似。
silverlight支持在TextBox中用AcceptsReturn="True" 来换行,但是TextBlock不支持此属性,因此需要在显示在TextBlock上的文字做些改变。
1.用"\n"换行
1
txbView.Text =
"Hello World\nMy Name is Jerry\nHaha"
;
效果
2.用silverlight自带的类
1
txbView.Inlines.Add(
new
LineBreak());
2
txbView.Inlines.Add(
new
Run() { Text =
"I’m"
});
3
txbView.Inlines.Add(
new
LineBreak());
4
txbView.Inlines.Add(
new
Run() { Text=
"Jerry"
});
效果
本系列博文将使用微软RIA技术解决方案Silverlight以及扩展性管理框架Managed Extensibility Framework(MEF),以插件式架构设计为导线,分享本人在从事基于微软Silverlight技术构建的RIA系统中实施插件式系统架构设计的相关技术和经验。鉴于本人能力有限,如有不妥之处请各位朋友指正,大家共同学习、进步,谢谢!
软件的工业化使得软件复用已经从通用类库进化到了面向领域的应用框架。应用框架强调的是软件的设计重用性和系统的课扩展性,以缩短大型应用软件系统的开发周期,提高开发质量。应用软件开发的未来就在于提供一个开放的体系结构,以方便中间件的选择、组装和集成,应用框架的重用已成为软件开发生产中最有效的重用方式之一。面对这种发展趋势,呼之欲出的便是一种全新的、开放性的、高扩展性的架构体系,这里我将其命名为插件式架构(或许与别人口中的插件式架构有所区别)。
一、插件式架构设计概述
插件式架构设计近年来非常流行,其中Eclipse起了推波助澜的作用,提到插件式就会不由自主的想到饿Eclipse。其实插件式设计并不是什么新事物,早在几十年前就有了。像X-Server就是基于插件式设计的,除了核心功能外,它所有的扩展功能和设备驱动都是以插件方式加入进来的。
基于插件的设计好处很多,把扩展功能从框架中剥离出来,降低了框架的复杂度,让框架更容易实现。扩展功能与框架以一种很松的方式耦合,两者在保持接口不变的情况下,可以独立变化和发布。公开插件接口,让第三方有机会扩展应用程序的功能,有财大家一起发。另外,还可以让开源与闭源共存于一套软件,你的插件是开源还是闭源,完全由你自己决定。基于插件设计并不神秘,相反它比起一团泥的设计更简单,更容易理解。各种基于插件设计的架构都有自己的特色,但从总体架构上看,其模型都大同小异。
插件式架构设计中主要包括:插件框架、插件契约(服务)以及插件组件三部分组成。
1、插件框架:组织和管理系统插件的下载、装载、组合、实例化以及销毁,并提供整套完整的与后台服务通信的操作接口等。
2、插件契约(服务):插件契约以服务接口的形式存在,系统的所有插件全部通过实现系统框架统一的接口规范,偏于有效的组织、管理插件对象。
3、插件组件:插件组件既为具体的插件程序,实现了插件契约服务的一个独立的程序。
对于插件式应用框架的开发,关键是要识别出框架中的通用点和扩展点。基于这个原则,对于开发插件式应用框架的方法和步骤主要分以下三点:
1、分析并提取出框架中的通用点
2、分析并提取出框架中的扩展点
3、在应用框架的扩展点处根据系统配置信息动态加载实际需要的程序集(应用插件),动态创建实例对象并调用其服务。
二、插件式架构技术选型
在RIA(Silverlight、Flex等)技术发热的现在,很多企业已经开始使用RIA技术解决方案进行企业管理系统建设,采用RIA技术进行系统建设的最大优点就是将后台处理服务程序和前台UI展现实现了完全分离,且后台实现也不受到任何技术活平台的限制,使系统的整体建设灵活性增强、以及提高对其他外部系统的集成能力。之所里选择微软RIA技术解决方案Silverlight技术来实现插件式系统架构,主要取决于以下优点:
1、Silverlight发布的动态连接库(.dll)或程序包(.xap)更容易实现插件式架构。
2、Silverlight支撑Socket的及时消息通信。
3、Silverlight开发与Blend界面设计完美结合,更容易、快捷的实现UI风格。
4、基于HttpService/WebService/WCF的分布式通信服务借口,提高多系统异构集成能力。
5、应用统一的系统样式,更容易、方便的实现系统多UI风格。
6、友好的全屏模式及独特的OOB(Out-Of-Browser)模式支持。
7、丰富的动画效果以提供完美的用户体验。
8、跨平台、跨浏览器支持。
9、更多......
三、插件式架构设计的优点
可以说任何形式的架构设计实践工作无非就是从负责、繁琐的的研发过程中寻找一种相对方便、灵活、稳定、高扩展性的以及更加简单的一种新型技术实现方式,从而提高项目的整体开发进度和质量,减少开发人员的工作压力,间接的提高整个项目团队的工作效率。
采用插件式架构设计的优点主要体现在以下几个方面:
1)、降低系统各模块之间的互依赖性
在进行插件式开发中,任何一个系统功能模块、通用用户界面以及最小的图标等都可以插件的方式进行开发,从而提高了通用功能模块的重用性;各个功能进行独立开发,相互之间不存在互依赖性,使各个独立的功能都可以单独运行,也可以通过插件框架进行托管运行,从而提高了整个系统的灵活性;对于修改功能模块也不会影响到其他插件模块的正常运行,降低了系统的维护难度,提高了系统的可扩展性。
2)、系统模块独立开发、部署、维护
每个功能模块都可以按照插件契约服务接口所定义的服务接口以及相关的元数据的形式当做一个插件进行独立开发,开发完成编译后可独立运行,也可通过插件框架进行托管运行。理论上插件组件是不应该可以单独运行的,按照插件式架构原理来说,必须是通过插件管家托管才能运行。实际的开发中或许会因为各种的业务需求不同而不同,具体应该如何对插件开发进行约束,还得结合实际项目需求而定。
3)、根据需求动态的组装、分离系统
每个功能模块都可以当做一个插件进行开发,通过统一的配置文件维护插件包的部署信息,插件框架可根据活动情况动态从服务器上下载相应的xap插件包或者是.dll的动态库文件到客户端进行插件初始化创建,插件到框架的组合等,插件框架能够灵活的管理各个插件实例以及插件之间的通信机制,也支持插件的卸载。
三、插件式架构组件(MEF)
在MEF之前,人们已经提出了许多依赖注入框架来解决应用的扩展性问题,比如OSGI 实现以Spring 等等。在 Microsoft 的平台上,.NET Framework 自身内部包含组件模型和 System.Addin。同时存在若干种开源解决方案,包括 SharpDevelop 的 SODA 体系结构和“控制反转”容器(如 Castle Windsor、Structure Map、Spring.Net 以及Unity)。
虽然.NET平台下,包括MS在内的各种方案已经遍地开花,但是MEF是第一个随着CLR发布的解决方案。
官方说法: Managed Extensibility Framework(MEF)是.NET平台下的一个扩展性管理框架,它是一系列特性的集合,包括依赖注入(DI)以及Duck Typing等。MEF为开发人员提供了一个工具,让我们可以轻松的对应用程序进行扩展并且对已有的代码产生最小的影响,开发人员在开发过程中根据功能要求定义一些扩展点,之后扩展人员就可以使用这些扩展点与应用程序交互;同时MEF让应用程序与扩展程序之间不产生直接的依赖,这样也允许在多个具有同样的扩展需求之间共享扩展程序。
本系列文章所讨论的插件式框架的设计采用.NET 4.0中的MEF框架作为核心组件,MEF的详细可查看我写的《MEF程序设计指南》系列博文。
架构设计并不是项简单的工作,架构设计最终的产物则是由不同的框架组件构成一套高扩展、稳定、安全、通用的开发框架平台。或许一提到架构设计,很多朋友都联想到了常用的框架组件:数据访问组件、日志组件、事务组件、消息组件、配置组件以及工具库等。然而,本系列文章的中心“插件式框架设计”已经偏离了常规的框架设计方法论,它只是一套用于改善系统功能模块组织结构,灵活开发、部署、维护的一套方法论,其中的每个功能模块的具体实现还是走常规的开发框架,它自身的职责则主要是负责根据配置文件实现系统功能模块的组装,灵活的卸载某个部件以及各部件之间如何通信等。
本篇将和大家分享基于Silverlight的B/S插件式架构设计的方法,文中的内容仅仅只是我个人知识、经验的总结,如有不妥之处还望各位读者给予指正,大家共同学习,进步。
对于Silverlight项目而言,前端系统需要后台服务接口的支撑才能完成数据通信访问、储存数据的的功能。通常需要给Silverlight前端提供相应的数据通信接口,可分为多种方式提供,常用的数据通信接口分别有Socket、HttpHandler、WebService以及WCF等方式。详细的架构模型如下图所示:
系统后台采取的技术架构为是竖向分成架构模式+横向扩展架构模式相结合,分成架构模式也就是众所周知的三层/多层架构,这里不做详细介绍;横向扩展架构模式则为支持横向业务扩展的架构模式,所有业务组件(我通常称其为:业务插件)通过实现统一的业务服务接口来扩展系统业务功能,系统框架中的业务组件容器(我通常称其为:业务插件容器)使用统一的业务服务接口灵活的管理业务组件,实现各组件之间的数据通信、事件通知、以及灵活的构造、销毁业务组件实例。总上述,这种架构模式我便称其为插件式架构设计。
插件式架构设计的框架能够灵活的横向扩展业务组件的扩展开发,管理业务组件的生命周期等,然而对于RIA应用系统来说,他只需要依赖一个或多个通信接口实现数据通信,不用关心服务后台的架构以及具体是实现细节。需要注重点则是关于系统前端的框架架构设计,一套基于Silverlight技术的插件式架构设计方法,通过插件框架灵活的加载、组合、初始化并进行托管运行系统插件模块,是我们期望达到的目的。如上所述,插件式框架的架构图大致如下所示:
系统前端的核心架构受到所采用的技术方案的影响,会演化出不同的架构设计方法和架构风格, 如前面所说我们采用的是RIA的技术Silverlight来进行技术构建,那么在进行系统架构设计中定会受到Silverlight技术自身的一些限制,以至于我们的设计不能按照常规的方法,方式去实现。
Silverlight能够为用户提供高用户体验的软件界面,以及传统的Web应用实现不了的很多功能,且也有很多的局限性,系统功能模块过多导致发布出来的应用程序包(.xap)过大,导致系统运行中初始化缓慢等诸多问题。我们需要一种全新的、开放性的、高扩展性的架构体系,来缓解这种因为技术自身的缺陷造成的诸多问题,可以实现快速的启动应用程序初始化界面,根据配置动态组装系统功能模块,以及灵活的扩展新的系统功能模块等功能,我将这种架构体系命名为插件式架构体系(或许与别人口中的插件式架构有所区别)。
如上图所示,描述了插件框架的框架结构,框架由插件容器、插件契约和插件组件(业务功能插件)三大部分组成,扩展开发新的插件组件需要实现插件契约接口,以便插件容器可以灵活的控制插件组件。关于这三大组成部分的作用请查看《插件式架构设计简介》,本篇对基于Silverlight插件式架构设计方法进行了介绍,下一篇将详细介绍插件式架构设计的解决方案。
推荐资料:
《MEF程序设计指南》:upload/2012/3/201203291107337043.png" width="415" height="307" />
默认的饼状图的样式是这样的,下面我一步一步地通过Blend对该控件的ControlTemplate进行简单的修改。
我是用Vs2010+Blend3进行配合的,首先在Vs的xaml文件上点右键在Blend中打开该解决方案:
打开后,选择该Chart-〉右键出现菜单-〉选择EditTemplate
这里EditTemplate下又分为Edit Current,Edit a Copy ,Create Empty等,如果你对Blend不是太熟悉,
建议把这几个选项都试一下,这里我们选择Edit a Copy,这是会弹出一个对话框
这个对话框就是用来定义资源的Key与位置的,Silverlight中的样式是不支持Apply to All的,这里的位置分为3种情况
选择Application,那么样式会定义在App.xaml中,也可以定义在资源字典中,默认是定义在当前页面的,这里按照默认方式来
完成后注意页面的一点变化,在页面左上角默认选中Chart的Template属性:
这里简单的介绍下Chart控件的几个部件:
那么比如这里需要对Legend样式进行改变,只需要打开Object and TimeLine,会看到Blend显示了该Template的VisualTree
选择Legend元素,然后进行设置相关的属性即可,其实也可以通过xaml进行
你会发现我们之前Create A Copy就是复制一份了Chart默认的样式,当然不建议直接改动xaml代码来修改样式。
我们简单的看看修改后的效果图:
其实还是可以修改的更好看一点,放张网上的效果图:
这主要还是看个人创意了..个人觉得程序员还是要懂艺术的,不然生活缺少了很多发现美的机会。。
好吧,这篇就到这里。
我们利用最为基本的控件,实现类似于视频网址的全屏功能,这里我们用的控件是,canvas控件stackpanel控件,textblock控件,以及button控件,其中textblock控件类似于asp.net中的label控件,用于显示数据,下面是silverlight创建及实现代码
1.首先我们新建一个silverlight项目:先在左面选择silverlight,然后选择silverlight应用程序,确定即可
.
2.在新建silverlight应用程序中选择你要新建的项目类型:asp.net web 应用程序、asp.net 网站、asp.net mvc web 应用程序,确定即可。
3.在右侧的解决方案管理器中双击MainPage.xaml
4.点击xaml开启我们的silverlight之旅
5.首先你会在刚刚新建的silverlight程序中看到微软已近给我们的部分代码,这里要删除,标签,在删除grid标签后,要引用命名空间:
using System.Windows.Interop;
在其位置添加如下代码:
<Canvas Background="Black">
<Button x:Name="btnContent" Click="btnContent_Click"
Canvas.Left="50" Canvas.Top="50" Background="Red" FontSize="12" Width="160"Height="80">
<Button.Content>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"VerticalAlignment="Center">
<TextBlock Text="点击我¨°" VerticalAlignment="Center"Margin="10" >TextBlock>
StackPanel>
Button.Content>
Button>
Canvas>
学习过asp.net 的相信对这些熟悉都不陌生,对于以上控件的使用请查看连接,在html中的很多规则是可用的,方便记忆以及学习,添加上如上代码后,我们可以所写即所得的看到
我们的效果差不多就是这样了,当然运行起来更为华丽
6.上面我们注意到会有个单击事件,点击button按钮时会实现相应的功能,可以将光标放到单击事件的名称处,在键盘上点击F7,直接生成单击事件,并进入单击事件代码处,添加如下代码:
Content contentObject = Application.Current.Host.Content;
contentObject.IsFullScreen = !contentObject.IsFullScreen;
这里把程序当前的所有内容赋给content的一个对象,下面的代码就是对现在浏览器的判断,看是否已经全屏显示,如果不是全屏显示的话,单击button按钮就会全屏显示,如果是全屏显示的话,单击按钮,退出全屏显示。
7.运行后的效果图如下:
点击button按钮后显示效果:
开发需要,做了一个简单的播放器,主要利用了MediaElement控件,实现了一下几个小功能
1,全屏
2,进度控制
3,静音
4,暂停,播放,停止
<MediaElement MouseLeftButtonUp="mediaElement1_MouseLeftButtonUp" AutoPlay="True" x:Name="mediaElement1" />
1,为了实现在视频播放时双击界面进行全屏,在MediaElement上对MouseLeftButtonUp事件中鼠标的点击做了计算和对比,两次点击在一秒内就认为是双击。
private void mediaElement1_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (list.Count == 0)
{
list.Add(DateTime.Now.Second);
}
else
{
if (list.Count == 1)
{
if (((int)list[0]) == DateTime.Now.Second)
{
Application.Current.Host.Content.IsFullScreen = !Application.Current.Host.Content.IsFullScreen;
}
list.Clear();
}
}
}
2,进度控制方面使用了Slider控件来控制,即Slider的范围是0-10,当拖动到3时,则认为是对应的视频进度为3/10,则视频的应设置进度在总长度*(3/10)
private void process_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
double currentValue=this.process.Value;
double rate = currentValue / 10;
double value = this.mediaElement1.NaturalDuration.TimeSpan.Ticks * rate;
this.mediaElement1.Position = new TimeSpan((long)value);
}
3,静音和暂停播放都比较简单
this.mediaElement1.IsMuted = true;
this.mediaElement1.Pause();
this.mediaElement1.Play();
this.mediaElement1.Stop();
首先得先安装那个4.7M的Silverlight.exe,可以从官网上下载到,相当于flashplayer那样的浏览器插件吧
然后就把下载到的那个31.1M的Silverlight3_Tools.exe右键解压到一个文件夹中,按照下图所示按顺序双击安装即可,下面的安装顺序是我自己试的,可能有些步骤是不必要的吧,安装完后重新启动VS就可以看到有silverlight的项目了
这样再安装上blend就可以开始进行SL的开发学习了,做出实例后如果要放到网上让别人能够看得到的,还得在你购买的空间后台那添加自定义的MIME类型,要不然是不能运行SL的,如下:
引用扩展名: .xap MIME类型:xapapplication/x-silverlight
扩展名: .xaml MIME类型:application/xaml+xml
Silverlight具备很好的用户体验,但有时需要在页面的布局上进行特殊处理,比如作为webpart集成到Sharepoint中等等。 HTML和Silverlight之间的双向交互可以更灵活的使用Silverlight进行开发,上午摸索了一下,记录在此。 一,向Silverlight传递数据,实现个性化加载 Silverlight在HTML中的引用是: 这种引用插件的方式提供了一系列的参数来实现个性加载,上面的代码中我们加了一行参数 我们可以在Silverlight中处理这些参数,打开Silverlight应用程序的App代码文件,加上接收参数的代码 我们看到对e.InitParams的处理,即可得到了HTML中传进来的参数,实现个性化加载: private void Application_Startup(object sender, StartupEventArgs e) { if (e.InitParams.Count != 0) { foreach(var item in e.InitParams) { this.Resources.Add(item.Key, item.Value); } } this.RootVisual = new MainPage(); } if(App.Current.Resources["CategoryId"]!=null) { int cateId = int.Parse(App.Current.Resources["CategoryId"].ToString()); CategoryItem c = new CategoryItem(); c.CategoryID = cateId; this.gridOfList.Children.Add(c); } 二,Silverlight调用HTML中的脚本资源,实现自身的样式等修改首先我们可以在加载Silverlight组件的页面上编写一段Javascript脚本 function InvokePlayer(videoId) { document.getElementById("divCategory").style.display = "none"; var player = document.getElementById("divPlayer"); player.style.width = "100%"; player.style.height = "600px"; } 怎么在Silverlight中调用这个脚本呢?我们可以在某个事件中调用Silverlight提供的类方法 System.Windows.Browser.HtmlPage.Window.Invoke("InvokePlayer", videoId); 当然类似的方法还有几个: (HtmlPage.Window.GetProperty("InvokePlayer") as ScriptObject)InvokeSelf("Good Function!"); HtmlPage.Window.Eval("document.getElementById(’result’)") as HtmlElement… 即可实现调用脚本。经过以上的两个方法即可实现HTML和Silverlight之间双向传递数据的功能。
5步教你在Silverlight中使用WCF服务
在Silverlight中如何使用WCF服务呢?本文针对初学者:5步在Silverlight中使用WCF服务
步骤一:创建WCF服务
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace WcfService1
{
// 注意: 如果更改此处的类名“Service1”,也必须更新 Web.config 和关联的 .svc 文件中对“Service1”的引用。
public class Service1 : IService1
{
public string GetData(int value)
{
return string.Format("You entered: {0}", value);
}
public CompositeType GetDataUsingDataContract(CompositeType composite)
{
if (composite.BoolValue)
{
composite.StringValue += "Suffix";
}
return composite;
}
}
}
2.第二步:
在WCF服务中添加跨域策略文件:
lientaccesspolicy.xml
<?xml version="1.0" encoding="utf-8" ?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers="*">
<domain uri="*"/>
</allow-from>
<grant-to>
<resource include-subpaths="true" path="/"/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>
crossdomain.xml
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM
"http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-http-request-headers-from domain="*" headers="*"/>
</cross-domain-policy>
3.第三步:创建Silverlight项目
4.第四步:在刚才创建的Silverlight项目中添加WCF服务的引用
5.修改ServiceReferences.ClientConfig文件,如下:
<configuration>
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="BasicHttpBinding_IService1" maxBufferSize="2147483647"
maxReceivedMessageSize="2147483647">
<security mode="None" />
</binding>
</basicHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:1914/Service1.svc" binding="basicHttpBinding"
bindingConfiguration="BasicHttpBinding_IService1" contract="ServiceReference1.IService1"
name="BasicHttpBinding_IService1" />
</client>
</system.serviceModel>
</configuration>
6.第六步:在xaml的后台代码中 调用WCF服务 :
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 SilverLightWCFService.ServiceReference1;
namespace SilverLightWCFService
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
Service1Client obj = new Service1Client();
obj.GetDataCompleted += new EventHandler<GetDataCompletedEventArgs>(obj_GetDataCompleted);
obj.GetDataAsync(980);
}
void obj_GetDataCompleted(object sender, GetDataCompletedEventArgs e)
{
//throw new NotImplementedException();
Mytext.Text = e.Result.ToString();
}
}
}
完成后运行程序,观察结果。