快速浏览Silverlight3 Beta: 在多个Silverlight应用间传递信息
在去年我曾经写过一篇文章,介绍如何在同一页面下多个Silverlight应用间传递事件信息,当时所使用的技巧就是借助HTML页面元素来传递,当然这种方式也支持向其它第三方ActiveX控件传递信息。但因为引入了JS代码,让开发者感觉有些别扭。必定这种消息传递写在 CS代码中会更容易被接受。
好在Silverlight3 beta中提供了两个重要的类,它们都是以“LocalMessage”打头,其位于“System.Windows.Messaging”名空间下:
LocalMessageSender :消息发送器类
LocalMessageReceiver:消息接收器类
顾名思义,它们就是所谓消息的“发送方”和“接收方”。
而使用它们也很简单,首先我们要先创建一个Silverlight3 Beta项目,名为:LocalMessage。然后将下面的XAML代码复制到MainPage.xaml文件中:
LocalMessageReceiver:消息接收器类
顾名思义,它们就是所谓消息的“发送方”和“接收方”。
而使用它们也很简单,首先我们要先创建一个Silverlight3 Beta项目,名为:LocalMessage。然后将下面的XAML代码复制到MainPage.xaml文件中:
<UserControlx:Class="LocalMessage.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400"Height="200">
<StackPanelx:Name="LayoutRoot"Background="AliceBlue">
<TextBox
Margin="10"
FontSize="24"
x:Name="txtMessage"/>
<Button
Content="发送"
HorizontalAlignment="Right"
Margin="10"
Click="OnSendMessage"/>
<TextBlockTextWrapping="Wrap"
Foreground="Blue"
FontSize="12"
x:Name="txtResponse"
HorizontalAlignment="Center"/>
</StackPanel>
</UserControl>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400"Height="200">
<StackPanelx:Name="LayoutRoot"Background="AliceBlue">
<TextBox
Margin="10"
FontSize="24"
x:Name="txtMessage"/>
<Button
Content="发送"
HorizontalAlignment="Right"
Margin="10"
Click="OnSendMessage"/>
<TextBlockTextWrapping="Wrap"
Foreground="Blue"
FontSize="12"
x:Name="txtResponse"
HorizontalAlignment="Center"/>
</StackPanel>
</UserControl>
下面是相应的CS代码:
voidOnSendMessage(objectsender,RoutedEventArgsargs)
{
LocalMessageSendermsgSender=newLocalMessageSender("MessageContact","localhost");
EventHandler<SendCompletedEventArgs>handler=null;
handler=(s,e)=>
{
Dispatcher.BeginInvoke(()=>
{
msgSender.SendCompleted-=handler;
if(e.Error!=null)
{
txtResponse.Text=String.Format("错误[{0}]",e.Error.Message);
}
else
{
txtResponse.Text=String.Format("响应[{0}]",e.Response==null?"None":e.Response);
}
});
};
msgSender.SendCompleted+=handler;
msgSender.SendAsync(txtMessage.Text);
}
{
LocalMessageSendermsgSender=newLocalMessageSender("MessageContact","localhost");
EventHandler<SendCompletedEventArgs>handler=null;
handler=(s,e)=>
{
Dispatcher.BeginInvoke(()=>
{
msgSender.SendCompleted-=handler;
if(e.Error!=null)
{
txtResponse.Text=String.Format("错误[{0}]",e.Error.Message);
}
else
{
txtResponse.Text=String.Format("响应[{0}]",e.Response==null?"None":e.Response);
}
});
};
msgSender.SendCompleted+=handler;
msgSender.SendAsync(txtMessage.Text);
}
在上面代码中,先声明一个 LocalMessageSender对象,因为该类的构造方法被重载,支持两个方式,相应参数说明如下:
ReceiverName:接收器名称,因为发送与接收方必须使用相应的ReceiverName,这一点大家可以想一想我们平时打电话必须拨某一号码才能与某人通信。
ReceiverDomain:获取LocalMessageReceiver的域信息(只有指定的域才能获取消息),这主要是解决跨域和安全性问题
ReceiverDomain:获取LocalMessageReceiver的域信息(只有指定的域才能获取消息),这主要是解决跨域和安全性问题
这里ReceiverDomain还可使用System.Windows.Messaging.LocalMessageSender.Global,这样就设置为Global域了。
在绑定相应的方法(SendCompleted)之后就可发送异步消息了。
接下来介绍一下接收方代码。
首先要先创建一个接收方的Silverlight应用,这里命名为“LocalMessageReceiver”。下面是相应的XAML代码:
接下来介绍一下接收方代码。
首先要先创建一个接收方的Silverlight应用,这里命名为“LocalMessageReceiver”。下面是相应的XAML代码:
<UserControlx:Class="LocalMessageReceiver.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400"Height="200">
<Gridx:Name="LayoutRoot"Background="Blue">
<TextBlock
Foreground="White"
FontSize="12"
x:Name="txtMessage"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</UserControl>
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Width="400"Height="200">
<Gridx:Name="LayoutRoot"Background="Blue">
<TextBlock
Foreground="White"
FontSize="12"
x:Name="txtMessage"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</UserControl>
而CS代码如下所示:
voidOnLoaded(objectsender,RoutedEventArgsargs)
{
List<string>allowedSenderDomains=newList<string>();
allowedSenderDomains.Add("silverlightshow.net");
allowedSenderDomains.Add("[url]http://www.silverlightshow.net/[/url]");
allowedSenderDomains.Add("localhost");
//下面使用全命名主要是项目名称与已有的LocalMessageReceiver重名所致
System.Windows.Messaging.LocalMessageReceiverreceiver=
newSystem.Windows.Messaging.LocalMessageReceiver("MessageContact",ReceiverNameScope.Domain,allowedSenderDomains);
receiver.MessageReceived+=(s,e)=>
{
e.Response="接收方收到消息!";
Dispatcher.BeginInvoke(()=>
{
txtMessage.Text=String.Format("收到信息[{0}]",e.Message);
});
};
receiver.Listen();
}
{
List<string>allowedSenderDomains=newList<string>();
allowedSenderDomains.Add("silverlightshow.net");
allowedSenderDomains.Add("[url]http://www.silverlightshow.net/[/url]");
allowedSenderDomains.Add("localhost");
//下面使用全命名主要是项目名称与已有的LocalMessageReceiver重名所致
System.Windows.Messaging.LocalMessageReceiverreceiver=
newSystem.Windows.Messaging.LocalMessageReceiver("MessageContact",ReceiverNameScope.Domain,allowedSenderDomains);
receiver.MessageReceived+=(s,e)=>
{
e.Response="接收方收到消息!";
Dispatcher.BeginInvoke(()=>
{
txtMessage.Text=String.Format("收到信息[{0}]",e.Message);
});
};
receiver.Listen();
}
我们看到这里LocalMessageReceiver类实例实始化参数,其中: 下面我们看一下效果:

当然如果发送方没有采用与接收方相同的ReceiverName或者发送方的ReceiverDomain未出现在接收方的AllowedSenderDomains列表中,就会出现错误。这一点大家下载源码后运行一下就可以了。
当然如果发送方没有采用与接收方相同的ReceiverName或者发送方的ReceiverDomain未出现在接收方的AllowedSenderDomains列表中,就会出现错误。这一点大家下载源码后运行一下就可以了。
ReceiverName:参见上面的LocalMessageSender
NameScope:ReceiverNameScope.Domain,该枚举参数用于标识是Domain还是Global。
AllowedSenderDomains:允许发送的域信息。
NameScope:ReceiverNameScope.Domain,该枚举参数用于标识是Domain还是Global。
AllowedSenderDomains:允许发送的域信息。
因为之前发送方已指定了域信息,即“localhost”,所以这里在列表变量:allowedSenderDomains中添加了“localhost”,并标识以 ReceiverNameScope.Domain。
另外就是如果发送方设置的是LocalMessageSender.Global,那么在接收方必须相应是:
ReceiverNameScope.Global
这样才能确保信息的传递。
ReceiverNameScope.Global
这样才能确保信息的传递。
本文出自 “代震军:用最好的心情面对最坏的事情” 博客,请务必保留此出处http://daizhj.blog.51cto.com/285189/143887