本文以实战一个基于silverlgiht,wcf,linq to sql的网站广告轮播器,可能并没有太大实际意义,不过相信可以体验出新一代技术的特性.我并且假定你已经有一定对这些技术的基础认识.
目标:
1.简单的网站嵌入单件silverlight.(嵌入到网站)
1.1.图片轮播.视频轮播.
2.网络传输使用wcf服务,使用(basicHttpBinding)
2.1.支持使用基于流的上传与下载资源(图片,视频)
3.使用sql server 2005作为数据存储.
3.1.使用linq to sql进行数据库操作.
A.系统规划:设想中的系统框架
B.需求分析:使用用例驱动模型设计出基础需求.
广告表:
记录广告一些基础数据
ADTable
1. int id (主键)(自增1)
2. int sort (0为图片广告,1为视频广告)
3. nvarchar(MAX) title(广告标题)
4. nvarchar(MAX) img(图片服务器文件路径)
5. nvarchar(MAX) video(视频服务器文件路径).
6. nvarchar(MAX) clickurl(用户点击广告后的超连接地址)
管理者表:
记录管理者的登陆名及登陆密码
adminTable
1. int id(主键) (自增1)
2. nvarchar(50) admin_name(管理员登陆名)
3. nvarchar(50) admin_pwd(管理员密码)
参数设置表:
记录一些参数的设定值
settingTable
1. int id(主键) (自增1)
2. nvarchar(50) set_name(设定名)
3. nvarchar(50) set_value(设定值)
D.建立wcf服务项目
启动vs2008->文件->新建->项目->visual c#->web->wcf服务应用程序
名称:jacService
如图:
此时项目建立成功.如图:
项目已自动生成一个wcf服务,并有测试的接口.我们手动把这此自动生成有代码删除.
IService1.cs变成:
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace jacService
{
[ServiceContract]
public interface IService1
{
}
}
Service1.svc.cs
添加SvcConfigEditor.exe工具:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
namespace jacService
{
public class Service1 : IService1
{
}
}
E.
解决方案资源管理器右键web.config->打开方式->添加->(程序名右边的”…”按扭->C:/Program Files/Microsoft SDKs/Windows/v6.0A/Bin/ (如果你安装开发平台时使用了默认路径,将会在这个路径中找到)->选中SvcConfigEditor.exe ->打开->确定
如图:
此时”打开方式”对话框会新增这个工具的打开方式:
如图:
这里我介绍一下这个工具的作用.
Wcf是一种可以用配置文件设定大部份功能的技术,所以它的配置参数可以是相当复杂,如果我们在使用这个配置时使用纯手工方式编将会带来一些不必要的错误,所以windows sdk中自带了这个工具.你可以通过这个ScvConfigEditor.exe配置复杂的wcf配置文件,而且使用相当直观,可以为你的编写wcf配置文件时节省时间和免除不必要的错误.
关于这个工具的一些使用,我会在另写一编文章中深入说明.
操作继续:选中SvcConfigEditor.exe->确定
把Binding设定为basicHttpBinding.
如图:
添加一个新的”绑定”,选中左边配置中的”绑定”,点击右边的”新建绑定配置…”
如图:
选中basicHttpBinding-> 确定
如图:
设定,不设定readerQuotas将会导致无法以byte[]形式上传文件.
maxBufferSize="999999999" maxReceivedMessageSize="999999999"
readerQuotas
maxArrayLength="999999999" maxStringContentLength="999999999"
如图:
把绑定与服务关联:
如图:
点击”关闭”->保存. 到这里,web.config完成设定.
以下是完整的web.config中的wcf服务配置文件:
<system.serviceModel>
<bindings>
<basicHttpBinding>
<binding name="NewBinding0" maxBufferSize="999999999" maxReceivedMessageSize="999999999" >
<readerQuotas maxArrayLength="999999999" maxStringContentLength="999999999"/>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service behaviorConfiguration="jacService.Service1Behavior"
name="jacService.Service1">
<endpoint address="" binding="basicHttpBinding" bindingConfiguration="NewBinding0"
contract="jacService.IService1">
<identity>
<dns value="localhost" />
</identity>
</endpoint>
<endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="jacService.Service1Behavior">
<!-- 为避免泄漏元数据信息,请在部署前将以下值设置为 false 并删除上面的元数据终结点-->
<serviceMetadata httpGetEnabled="true"/>
<!-- 要接收故障异常详细信息以进行调试,请将以下值设置为 true。在部署前设置为 false 以避免泄漏异常信息-->
<serviceDebug includeExceptionDetailInFaults="false"/>
</behavior>
</serviceBehaviors>
</behaviors>
</system.serviceModel>
F.
跨域文件制作:
本于安全原因,silverlight如果要访问不同域名wcf服务必须要在wcf 服务的宿主建立一个跨域文件,否则会提示错误.
(注意:如果你的wcf服务的宿主是IIS,那么这个文件必须在IIS的根目录,而不是这个wcf服务的根目录)
操作:添加->新建项->xml文件->命名为:clientaccesspolicy.xml(这个文件名不可更改)->内容如下:
.如图:
完成.
G. 数据库连接,及linq to sql类的定义
1.连接数据库
服务器资源管理器->数据连接->添加连接
把你sql server连接上.如图:(并非所有人都一样)这里我把数据库命名为jacAdData)
2.添加linq to sql类
添加->新建项->Linq To Sql类->命名为adData.dbml
如图:
添加
3. 设计Linq to sql类
从左边的服务器资源管理器中拖放ad,admin,setting三个表到右边的空白处.
如图:
保存. 完成.
H.服务器端接口设计(为了简化复杂性,这些接口的设计没有考虑安全因数.)
[ServiceContract]
public interface IService1
{
#region 浏览端
//返回指定文件,以byte[]类型
[OperationContract]
byte[] getByte(string fileName);
#endregion
#region 返回所有AD
//取得所有广告
[OperationContract]
List<ad> getAD();
#endregion
#region 管理端
#region 增,删,改,查
//新增广告
[OperationContract]
bool addAD(ad data, bytedata ms);
//查询指定id的广告
[OperationContract]
ad selectAD(int id);
//删除广告
[OperationContract]
bool delete(int id);
//初始化数据库
[OperationContract]
bool insdata();
#endregion
#region 设置
//取得所有设定
[OperationContract]
List<setting> getsetting();
//修改设定
[OperationContract]
bool setdata(string key, string data);
#endregion
#region 密码修改
//登陆
[OperationContract]
bool login(string userid, string pwd);
//修改密码
[OperationContract]
bool updatepwd(string oldpwd, string pwd);
#endregion
#endregion
}
I.
接口实现
接口实现
接口实现
以下是Service1.svc.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using System.IO;
using System.Web.Hosting;
using System.ServiceModel.Activation;
namespace jacService
{
public class Service1 : IService1
{
//实例化linq to sql类
adDataDataContext dc = new adDataDataContext();
//定义图片和视频文件的路径
string filedir = HostingEnvironment.ApplicationPhysicalPath + @"data/";
#region IService1 成员
public byte[] getByte(string fileName)
{
//返回指定文件,以byte[]
return File.ReadAllBytes(filedir + fileName);
}
public List<ad> getAD()
{
//取得所有广告
return dc.GetTable<ad>().ToList();
}
//添加广告
public bool addAD(ad data, bytedata ms)
{
add(data, ms);
return true;
}
//查询
public ad selectAD(int id)
{
return dc.ad.Single(d => d.id == id);
}
//删除
public bool delete(int id)
{
//判断是否存在此广告,使用linq表达式
if ((from d in dc.ad where d.id == id select d).Count() > 0)
{
var data = dc.ad.Single(d => d.id == id);
//删除文件
if (File.Exists(filedir + data.video))
{
File.Delete(filedir + data.video);
}
if (File.Exists(filedir + data.img))
{
File.Delete(filedir + data.img);
}
//删除数据
dc.ad.DeleteOnSubmit(data);
dc.SubmitChanges();
}
return true;
}
//初始化数据库,及文件夹
public bool insdata()
{
try
{
var myad = dc.GetTable<ad>();
foreach (var mad in myad)
{
dc.ad.DeleteOnSubmit(mad);
}
dc.SubmitChanges();
Directory.Delete(HostingEnvironment.ApplicationPhysicalPath + "data",true);
Directory.CreateDirectory(HostingEnvironment.ApplicationPhysicalPath + "data");
return true;
}
catch
{
return false;
}
}
//取得所有设定
public List<setting> getsetting()
{
return dc.GetTable<setting>().ToList();
}
//设定参数
public bool setdata(string key, string data)
{
//查询指定记录,使用lambda表达式
var ndata = dc.setting.Single(d => d.set_name == key);
ndata.set_value = data;
dc.SubmitChanges();
return true;
}
//管理员登陆
public bool login(string userid, string pwd)
{
if ((from i in dc.admin where i.admin_name==userid select i).Count() >0)
{
admin data = dc.admin.Single(d => d.admin_name == userid);
if (data.admin_pwd == pwd)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
//管理员修改密码
public bool updatepwd(string oldpwd, string pwd)
{
var user = dc.admin.Single(d => d.admin_name == "admin");
if (oldpwd.Equals(user.admin_pwd))
{
user.admin_pwd = pwd;
dc.SubmitChanges();
return true;
}
else
{
return false;
}
}
#endregion
//新增操作
void add(ad data, bytedata ms)
{
if (data.sort == 0)
{
StreamToFile(ms.filedata, filedir + data.img);
dc.ad.InsertOnSubmit(data);
dc.SubmitChanges();
}
else if (data.sort == 1)
{
StreamToFile(ms.filedata, filedir + data.video);
dc.ad.InsertOnSubmit(data);
dc.SubmitChanges();
}
}
//将流写为文件
void StreamToFile(byte[] bytes, string fileName)
{
FileStream fs = new FileStream(fileName, FileMode.Create);
BinaryWriter bw = new BinaryWriter(fs);
bw.Write(bytes);
bw.Close();
fs.Close();
}
}
//数据契约
[DataContract]
public class bytedata
{
[DataMember]
public byte[] filedata { get; set; }
}
}
J.
1.打开adData.designer.cs文件:如图:
数据契约说明:在wcf开发中,当我们需要传输一些我们自定义的数据类型时,这些数据类型都必须为可序列化和返序列化,wcf为我们提供了十方便的使用方式,只要在数据定义时加上DataContract"数据契约"即可,这样自定义数据在传输过程中会自动序列化和反序列化,而DataMember即为数据契约的成员,如果数据契约成员没有被标识为DataMember,那么wcf会视此成员为不进行序列化和反序列化.以下是一个简单的例子:
//数据契约
[DataContract]
public class mydata
{
//数据成员
[DataMember]
public string userid { get; set; }
//数据成员
[DataMember]
public int age { get; set; }
//非数据成员
public string address { get; set; }
}
2.添加System.Runtime引用.
以下是整个adData.designer.cs文件修改后的内容,(注意using System.Runtime.Serialization;和
[DataContract],[DataMember]和定义.)
namespace jacService
{
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
using System.ComponentModel;
using System;
using System.Runtime.Serialization;
[System.Data.Linq.Mapping.DatabaseAttribute(Name="jacADdata")]
public partial class adDataDataContext : System.Data.Linq.DataContext
{
private static System.Data.Linq.Mapping.MappingSource mappingSource = new AttributeMappingSource();
#region Extensibility Method Definitions
partial void OnCreated();
partial void Insertad(ad instance);
partial void Updatead(ad instance);
partial void Deletead(ad instance);
partial void Insertadmin(admin instance);
partial void Updateadmin(admin instance);
partial void Deleteadmin(admin instance);
partial void Insertsetting(setting instance);
partial void Updatesetting(setting instance);
partial void Deletesetting(setting instance);
#endregion
public adDataDataContext() :
base(global::System.Configuration.ConfigurationManager.ConnectionStrings["jacADdataConnectionString"].ConnectionString, mappingSource)
{
OnCreated();
}
public adDataDataContext(string connection) :
base(connection, mappingSource)
{
OnCreated();
}
public adDataDataContext(System.Data.IDbConnection connection) :
base(connection, mappingSource)
{
OnCreated();
}
public adDataDataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public adDataDataContext(System.Data.IDbConnection connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
base(connection, mappingSource)
{
OnCreated();
}
public System.Data.Linq.Table<ad> ad
{
get
{
return this.GetTable<ad>();
}
}
public System.Data.Linq.Table<admin> admin
{
get
{
return this.GetTable<admin>();
}
}
public System.Data.Linq.Table<setting> setting
{
get
{
return this.GetTable<setting>();
}
}
}
[DataContract]
[Table(Name="dbo.ad")]
public partial class ad : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _id;
private int _sort;
private string _title;
private string _img;
private string _video;
private string _clickurl;
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnidChanging(int value);
partial void OnidChanged();
partial void OnsortChanging(int value);
partial void OnsortChanged();
partial void OntitleChanging(string value);
partial void OntitleChanged();
partial void OnimgChanging(string value);
partial void OnimgChanged();
partial void OnvideoChanging(string value);
partial void OnvideoChanged();
partial void OnclickurlChanging(string value);
partial void OnclickurlChanged();
#endregion
public ad()
{
OnCreated();
}
[DataMember(Order=1)]
[Column(Storage="_id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int id
{
get
{
return this._id;
}
set
{
if ((this._id != value))
{
this.OnidChanging(value);
this.SendPropertyChanging();
this._id = value;
this.SendPropertyChanged("id");
this.OnidChanged();
}
}
}
[DataMember(Order = 2)]
[Column(Storage="_sort", DbType="Int NOT NULL")]
public int sort
{
get
{
return this._sort;
}
set
{
if ((this._sort != value))
{
this.OnsortChanging(value);
this.SendPropertyChanging();
this._sort = value;
this.SendPropertyChanged("sort");
this.OnsortChanged();
}
}
}
[DataMember(Order = 3)]
[Column(Storage="_title", DbType="NVarChar(MAX) NOT NULL", CanBeNull=false)]
public string title
{
get
{
return this._title;
}
set
{
if ((this._title != value))
{
this.OntitleChanging(value);
this.SendPropertyChanging();
this._title = value;
this.SendPropertyChanged("title");
this.OntitleChanged();
}
}
}
[DataMember(Order = 4)]
[Column(Storage="_img", DbType="NVarChar(MAX)")]
public string img
{
get
{
return this._img;
}
set
{
if ((this._img != value))
{
this.OnimgChanging(value);
this.SendPropertyChanging();
this._img = value;
this.SendPropertyChanged("img");
this.OnimgChanged();
}
}
}
[DataMember(Order = 5)]
[Column(Storage="_video", DbType="NVarChar(MAX)")]
public string video
{
get
{
return this._video;
}
set
{
if ((this._video != value))
{
this.OnvideoChanging(value);
this.SendPropertyChanging();
this._video = value;
this.SendPropertyChanged("video");
this.OnvideoChanged();
}
}
}
[DataMember(Order = 6)]
[Column(Storage="_clickurl", DbType="NVarChar(MAX) NOT NULL", CanBeNull=false)]
public string clickurl
{
get
{
return this._clickurl;
}
set
{
if ((this._clickurl != value))
{
this.OnclickurlChanging(value);
this.SendPropertyChanging();
this._clickurl = value;
this.SendPropertyChanged("clickurl");
this.OnclickurlChanged();
}
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected virtual void SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
[DataContract]
[Table(Name="dbo.admin")]
public partial class admin : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _id;
private string _admin_name;
private string _admin_pwd;
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnidChanging(int value);
partial void OnidChanged();
partial void Onadmin_nameChanging(string value);
partial void Onadmin_nameChanged();
partial void Onadmin_pwdChanging(string value);
partial void Onadmin_pwdChanged();
#endregion
public admin()
{
OnCreated();
}
[DataMember(Order = 1)]
[Column(Storage="_id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int id
{
get
{
return this._id;
}
set
{
if ((this._id != value))
{
this.OnidChanging(value);
this.SendPropertyChanging();
this._id = value;
this.SendPropertyChanged("id");
this.OnidChanged();
}
}
}
[DataMember(Order = 2)]
[Column(Storage="_admin_name", DbType="NVarChar(50)")]
public string admin_name
{
get
{
return this._admin_name;
}
set
{
if ((this._admin_name != value))
{
this.Onadmin_nameChanging(value);
this.SendPropertyChanging();
this._admin_name = value;
this.SendPropertyChanged("admin_name");
this.Onadmin_nameChanged();
}
}
}
[DataMember(Order = 3)]
[Column(Storage="_admin_pwd", DbType="NVarChar(50)")]
public string admin_pwd
{
get
{
return this._admin_pwd;
}
set
{
if ((this._admin_pwd != value))
{
this.Onadmin_pwdChanging(value);
this.SendPropertyChanging();
this._admin_pwd = value;
this.SendPropertyChanged("admin_pwd");
this.Onadmin_pwdChanged();
}
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected virtual void SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
[DataContract]
[Table(Name="dbo.setting")]
public partial class setting : INotifyPropertyChanging, INotifyPropertyChanged
{
private static PropertyChangingEventArgs emptyChangingEventArgs = new PropertyChangingEventArgs(String.Empty);
private int _id;
private string _set_name;
private string _set_value;
#region Extensibility Method Definitions
partial void OnLoaded();
partial void OnValidate(System.Data.Linq.ChangeAction action);
partial void OnCreated();
partial void OnidChanging(int value);
partial void OnidChanged();
partial void Onset_nameChanging(string value);
partial void Onset_nameChanged();
partial void Onset_valueChanging(string value);
partial void Onset_valueChanged();
#endregion
public setting()
{
OnCreated();
}
[DataMember(Order = 1)]
[Column(Storage="_id", AutoSync=AutoSync.OnInsert, DbType="Int NOT NULL IDENTITY", IsPrimaryKey=true, IsDbGenerated=true)]
public int id
{
get
{
return this._id;
}
set
{
if ((this._id != value))
{
this.OnidChanging(value);
this.SendPropertyChanging();
this._id = value;
this.SendPropertyChanged("id");
this.OnidChanged();
}
}
}
[DataMember(Order = 2)]
[Column(Storage="_set_name", DbType="NVarChar(50)")]
public string set_name
{
get
{
return this._set_name;
}
set
{
if ((this._set_name != value))
{
this.Onset_nameChanging(value);
this.SendPropertyChanging();
this._set_name = value;
this.SendPropertyChanged("set_name");
this.Onset_nameChanged();
}
}
}
[DataMember(Order = 3)]
[Column(Storage="_set_value", DbType="NVarChar(50)")]
public string set_value
{
get
{
return this._set_value;
}
set
{
if ((this._set_value != value))
{
this.Onset_valueChanging(value);
this.SendPropertyChanging();
this._set_value = value;
this.SendPropertyChanged("set_value");
this.Onset_valueChanged();
}
}
}
public event PropertyChangingEventHandler PropertyChanging;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void SendPropertyChanging()
{
if ((this.PropertyChanging != null))
{
this.PropertyChanging(this, emptyChangingEventArgs);
}
}
protected virtual void SendPropertyChanged(String propertyName)
{
if ((this.PropertyChanged != null))
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
到此. 服务器端已经设计完成.
运行后如图:
下一步客户端开发.
首先,我先行介绍一下一个有有到的工具软件.Expression Blend.此工具是专为wpf而开发UI设计工具,
可以很直观并快速的开发出理想的软件UI,也是程式员与UI工程师的分散协同工作工作,程序员可以用vs2008编写代码,UI工程师可以使用Blend开发UI,(Expression studio还有其他的一些工具,包括,design,encoder,media等,这里不祥说)
要想可以开发silverlight我们必须安装silverlight的开发扩展,目前是rc1,运行时是RTW.
安装地址(http://silverlight.net/GetStarted/)
现在我假定你的开发平台已经安装好所有开发工具(vs2008+silverlight Rc1扩展,silverlight RTW runtim,Expression blend)
K.建立AD客户端(silverlight)
1.解决方案->添加->新建项目->visual c#->silverlight->silverlight应用程序
名称:Persenter->确定->在生成时自动生成测试页以承载silverlgiht(G)
如图:
2.再用相同的方法添加管理者的silverlight客户端名称为(admin).此时项目资管理器中会多两个silvelight项目.如图:
L.引用wcf服务.(这里介绍如何在silverlight中引用wcf服务)
1.扩开Persenter项目:
右键引用->添加服务引用->地址->http://localhost:3725/Service1.svc(此为wcf服务地址,取得方法就是通过运行服务项目得到,如上服务设计完成图中的IE的url地址.)->确定->命名空间我不作修改使用ServiceReference1.此时项目会自动生成客户端的代理文件.
2.设计广告轮播器.
Persenter->右键page.xaml->在Expression Blend中打开->进入到blend中.
设计成如下:
<UserControl x:Class="Persenter.Page"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="Auto" Height="Auto">
<Grid x:Name="LayoutRoot" Background="#FFD0F284" Opacity="1">
<Image Margin="0,0.5,0,37" x:Name="img1" Stretch="UniformToFill"/>
<TextBlock Height="25" Margin="26,0,26,8" VerticalAlignment="Bottom" TextWrapping="Wrap" x:Name="tbk_title" Text="Title" TextAlignment="Center" Foreground="#FF4F4F39" HorizontalAlignment="Stretch" Cursor="Hand" Width="350" FontSize="14"/>
<TextBlock Height="25" HorizontalAlignment="Left" Margin="8,0,0,8" VerticalAlignment="Bottom" Width="14" Text="<" TextWrapping="Wrap" Foreground="#FFEC2B2B" x:Name="left"/>
<TextBlock Height="25" HorizontalAlignment="Right" Margin="0,0,8,8" VerticalAlignment="Bottom" Width="14" Text=">" TextWrapping="Wrap" x:Name="right" Foreground="#FFEC2B2B"/>
<MediaElement x:Name="video" Opacity="1" Volume="1" Margin="0,0,0,37"/>
</Grid>
</UserControl>
3.设计app.xaml.cs文件,让silverlight可以接受外来参数的传入.
namespace Persenter
{
public partial class App : Application
{
public IDictionary<string, string> inputdata;
private void Application_Startup(object sender, StartupEventArgs e)
{
this.RootVisual = new Page();
inputdata = e.InitParams;
}
这样我们可以通过设定silverlgiht所在的asp.net页中的控件定义参数为行数据传入.
例子:
<asp:Silverlight ID="Xaml1" runat="server" Source="~/ClientBin/Persenter.xap"
MinimumVersion="2.0.30523" Width="100%" Height="100%"
InitParameters="参数1名=参数1值,参数2名=参数2值"/>
使用时:
App myapp = App.Current as App;
var url = myapp.inputdata.Single(d => d.Key.Equals("参数1名"));
var Ivalue = url.Value;
4.添加一个新类以管理取得从外边传入的wcf服务地址.类名为(serverManager.cs)
这里实例了一个wcf服务的客户端代理.命名为sc.
而且定义了一个方法返回一个使用了传入服务地址的代理命名为getpox()
namespace Persenter
{
internal class serverManager
{
private static ServiceReference1.Service1Client sc = new Persenter.ServiceReference1.Service1Client();
internal static ServiceReference1.Service1Client getPox()
{
if (sc.State== System.ServiceModel.CommunicationState.Created)
{
App myapp = App.Current as App;
var url = myapp.inputdata.Single(d => d.Key.Equals("server"));
sc.Endpoint.Address = new System.ServiceModel.EndpointAddress(url.Value);
return sc;
}
else
{
return sc;
}
}
}
}
5.page.xaml.cs代码(这里是实现广告的核心)
namespace Persenter
{
public partial class Page : UserControl
{
//自定义的timer,这里我使用了Storyboard,利用Storyboard的conpleted事件不断重复.
Storyboard looper;
public Page()
{
InitializeComponent();
//实例化自定义timer
looper = new Storyboard();
//设定重复时间,这里默认值设为5秒
looper.Duration = new Duration(TimeSpan.FromSeconds(5));
//注册completed事件
looper.Completed += new EventHandler(looper_Completed);
//注册初始化事件
this.Loaded += new RoutedEventHandler(Page_Loaded);
//注册上翻事件
this.left.MouseLeftButtonDown += left_MouseLeftButtonDown;
//注册下翻事件
this.right.MouseLeftButtonDown += right_MouseLeftButtonDown;
}
//下翻时件
void right_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (sumer < counter)
{
sumer += 1;
}
showad(ads[sumer]);
looper.Stop();
looper.Begin();
}
//上翻事件
void left_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (sumer > 0)
{
sumer -= 1;
}
showad(ads[sumer]);
looper.Stop();
looper.Begin();
}
//timer重复事件
void looper_Completed(object sender, EventArgs e)
{
if (sumer < counter)
{
sumer += 1;
showad(ads[sumer]);
}
else if (sumer == counter)
{
sumer = -1;
}
looper.Begin();
}
//运算子
int sumer = 0;
int counter = 0;
//显示广告方法
void beginadshow(List<ad> data)
{
counter = data.Count() - 1;
showad(data[sumer]);
looper.Begin();
}
//wcf服务的客户端代理
Service1Client sc;
void Page_Loaded(object sender, RoutedEventArgs e)
{
//加载服务
sc = serverManager.getPox();
//注册控件的鼠标事件
tbk_title.MouseLeftButtonDown += tbk_title_MouseLeftButtonDown;
img1.MouseLeftButtonDown += tbk_title_MouseLeftButtonDown;
video.MouseLeftButtonDown += tbk_title_MouseLeftButtonDown;
//注册服务异步完成事件
sc.getByteCompleted += sc_getByteCompleted;
sc.getsettingCompleted += sc_getsettingCompleted;
sc.getADCompleted += sc_getADCompleted;
//异步调用wcf服务的getsetting和getad方法
sc.getsettingAsync();
sc.getADAsync();
}
//getsetting完成后的操作
void sc_getsettingCompleted(object sender, getsettingCompletedEventArgs e)
{
//取得返回结果(服务器端必须把setting定义为 [DataContract]才能在这里还原数据.
List<setting> set = new List<setting>(e.Result);
//取得setting后把属性设定
this.Width = double.Parse(set.Single(d => d.set_name == "宽度").set_value);
this.Height = double.Parse(set.Single(d => d.set_name == "高度").set_value);
this.tbk_title.FontSize = double.Parse(set.Single(d => d.set_name == "字体大小").set_value);
this.video.Volume = double.Parse(set.Single(d => d.set_name == "视频音量").set_value);
clickmode = int.Parse(set.Single(d => d.set_name == "连接方式").set_value);
}
//getad完成后的操作
void sc_getADCompleted(object sender, getADCompletedEventArgs e)
{
//取得广告集合
ads = new List<ad>(e.Result);
beginadshow(ads);
}
//用户点击后的超连接
Uri clickurl;
//广告集合定义
List<ad> ads;
//用户点击后的超连接方式,1:在当前页打开,0:从新页个打开.
int clickmode = 1;
//广告显示
void showad(ad d)
{
//image的souce属性初始化
img1.ClearValue(Image.SourceProperty);
//title显不
tbk_title.Text = d.title;
//取得超连接
clickurl = new Uri(d.clickurl);
//图片或视频的运算子,0:图片,1:视频
adsort = d.sort;
//判断并设定图片或视频到控件.
if (d.sort == 0)
{
video.Opacity = 0;
video.Stop();
//向服务器申请图片内容byte[]
sc.getByteAsync(d.img);
}
else if (d.sort == 1)
{
video.Opacity = 1;
//向服务器申请视频内容byte[]
sc.getByteAsync(d.video);
}
}
//定义图片或视频的运算子,0:图片,1:视频
int adsort = 0;
//向服务器申请视频内容byte[]完成
void sc_getByteCompleted(object sender, getByteCompletedEventArgs e)
{
//还原byte[]到图片或视频播控件
BitmapImage bi = new BitmapImage();
MemoryStream data = new MemoryStream(e.Result);
if (adsort == 0)
{
bi.SetSource(data);
img1.Source = bi;
}
else if (adsort == 1)
{
video.SetSource(data);
video.Play();
}
}
//鼠标点击事件
void tbk_title_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (clickmode == 1)
{
//以新页方式打开超连接
HtmlPage.Window.Navigate(clickurl, "blend");
}
else
{
//以本页方式打开
HtmlPage.Window.Navigate(clickurl);
}
}
}
}
到此广告轮播展示器完成,接下来我们开发管理者的silverlight端.
项目文件下载地址:http://www.codeplex.com/jacad
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/jacle169/archive/2008/11/18/3322753.aspx