在去年我曾经写过一篇文章,介绍如何在同一页面下多个Silverlight应用间传递事件信息, 当时所使用的技巧就是借助HTML页面元素来传递,当然这种方式也支持向其它第三方ActiveX控 件传递信息。但因为引入了JS代码,让开发者感觉有些别扭。必定这种消息传递写在 CS代码中 会更容易被接受。 好在Silverlight3 beta中提供了两个重要的类,它们都是以“LocalMessage”打头,其位于 LocalMessageSender :消息发送器类
<UserControl x: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"> <StackPanel x:Name="LayoutRoot" Background="AliceBlue"> <TextBox Margin="10" FontSize="24" x:Name="txtMessage" /> <Button Content=" 发 送 " HorizontalAlignment="Right" Margin="10" Click="OnSendMessage" /> <TextBlock TextWrapping="Wrap" Foreground="Blue" FontSize="12" x:Name="txtResponse" HorizontalAlignment="Center" /> </StackPanel> </UserControl>
下面是相应的CS代码: void OnSendMessage(object sender, RoutedEventArgs args)
{ LocalMessageSender msgSender = new LocalMessageSender("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); }
ReceiverName: 接收器名称,因为发送与接收方必须使用相应的ReceiverName,这一点大家可以
想一想我们平时打电话必须拨某一号码才能与某人通信。 ReceiverDomain:获取LocalMessageReceiver的域信息(只有指定的域才能获取消息),这主要 是解决跨域和安全性问题
在绑定相应的方法(SendCompleted)之后就可发送异步消息了。
<UserControl x: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"> <Grid x:Name="LayoutRoot" Background="Blue" > <TextBlock Foreground="White" FontSize="12" x:Name="txtMessage" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> </UserControl>
而CS代码如下所示: void OnLoaded(object sender, RoutedEventArgs args)
{ List<string> allowedSenderDomains = new List<string>(); allowedSenderDomains.Add( "silverlightshow.net" ); allowedSenderDomains.Add( "http://www.silverlightshow.net/" ); allowedSenderDomains.Add("localhost"); //下面使用全命名主要是项目名称与已有的LocalMessageReceiver重名所致 System.Windows.Messaging.LocalMessageReceiver receiver = new System.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:参见上面的LocalMessageSender
NameScope: ReceiverNameScope.Domain, 该枚举参数用于标识是Domain还是Global。 AllowedSenderDomains: 允许发送的域信息。 下面我们看一下效果: |
当然如果发送方没有采用与接收方相同的ReceiverName或者发送方的ReceiverDomain未出现在接收 方的AllowedSenderDomains列表中,就会出现错误。这一点大家下载源码后运行一下就可以了。 另外就是如果发送方设置的是LocalMessageSender.Global,那么在接收方必须相应是: |