Silverlight消息提醒功能,利用NotificationWindow
想在Silverlight中实现一个消息提醒功能,类似于QQ,在右下角弹出窗体。但发现Silverlight中的子窗体都没有类似WinForm中的StartPostion或Location属性,不能定义窗体出现的位置,好像还不能游离于父窗体之外 ,简单来说就是做不到一直在右下角显示。好在SL4中新增了一个功能NotificationWindow,用这个可以勉强实现我们所需的功能。
但用了NotificationWindow不得不吐槽一下,做得和鸡肋一样,有太多的限制了:
1 一次只能显示一个。
2 高度不能超过100,宽度不能超过400。
3 只能在OOB模式下使用。
4 显示时间最大不能超过30S。
5 窗体弹出位置没有刚好在右下角(要偏上一点),还无法自定义窗体出现的位置。
6 是密封类,不能继承。
好了,吐槽完了,说一下NotificationWindow的简单用法。
一般情况下,都是新建一个Silverlight用户控件:UpdateNotification.xaml来NotificationWindow的样式,如:
<Grid x:Name="LayoutRoot"> <Border x:Name="Frame" Width="300" Height="100" Background="LightYellow"> <StackPanel Orientation="Vertical"> <Border Width="290" Height="24" CornerRadius="4" Margin="2,4,2,4"> <Border.Background> <LinearGradientBrush StartPoint="0.5,0.0" EndPoint="0.5,1.0"> <GradientStop Offset="0.2" Color="#FF1C68A0" /> <GradientStop Offset="1.0" Color="#FF54A7E2" /> </LinearGradientBrush> </Border.Background> <Border.Effect> <DropShadowEffect BlurRadius="4" ShadowDepth="4" Opacity="0.4" /> </Border.Effect> <TextBlock Text="Update Available" FontSize="12" FontWeight="Bold" Foreground="White" Margin="4" /> </Border> <StackPanel Orientation="Horizontal"> <Image Source="Images/Update.png" Width="32" Height="34" Stretch="Fill" Margin="4" VerticalAlignment="Top" /> <TextBlock Width="240" Text="An updated version..." FontSize="11" Foreground="#FF202020" TextWrapping="Wrap" Margin="4" /> </StackPanel> </StackPanel> </Border> </Grid>
在后台代码中调用:
NotificationWindow win = new NotificationWindow(); UpdateNotification un = new UpdateNotification(); win.Width = un.Width; win.Height = un.Height; win.Content = un; win.Show(10000);
嗯,就这么简单,效果如下:
但是如果我们要实现NotificationWindow的手动关闭呢?原先我的想法是在UpdateNotification.xaml中增加一个Button,点击Button的时候来关闭NotificationWindow,但奇葩的是在UpdateNotification.xaml中定义的事件在后台竟然完全没有响应,这不坑爹嘛。Google了一下,网上说是在SL4中可以,但在SL5中就不行了。
没办法,只有所有的功能都拿到后台代码中来做了:在后台自己定义一个UserControl,然后往往里面加入控件来显示消息和关闭按钮。不过这样子,样式就丑很多了(好吧,是我自己不会设计==上面的是网上找的例子)
UserControl control = new UserControl(); control.Height = 100; control.Width = 200; //实例化一个Grid Grid grid = new Grid(); ... //关闭按钮 Button b = new Button(); b.Content = "关闭"; b.Click += b_Click;//关闭事件 ... control.Content = grid;
//nw即一个NofitycationWindow nw.Content = control;
b_Click事件:
private void b_Click(object sender, RoutedEventArgs e) { if (nw != null) { nw.Close(); } }
还有30S的时候间不是太短了点,为了让窗体一直显示,我们可以在窗体关闭的事件中再重新Show一下:
private void nw_Closed(object sender, EventArgs e) { if (msgList.Count > 0) { nw.Show(30000); } }
完整代码:
public class WindowMsgHelper { private static NotificationWindow nw = new NotificationWindow(); private static List<WindowsMsg> msgList = new List<WindowsMsg>(); public WindowMsgHelper() { nw.Width = 200; nw.Height = 100; nw.Closed+=nw_Closed; InitNW(); } private void nw_Closed(object sender, EventArgs e) { if (msgList.Count > 0) { nw.Show(30000); } } private void InitNW() { UserControl control = new UserControl(); control.Height = 100; control.Width = 200; //实例化一个Grid Grid grid = new Grid(); grid.Name = "mainGrid"; grid.Background = new SolidColorBrush(Color.FromArgb(255, 245, 245, 245)); //设置RowDefinition RowDefinition row1 = new RowDefinition(); row1.Height = new GridLength(20); grid.RowDefinitions.Add(row1); RowDefinition row2 = new RowDefinition(); row2.Height = new GridLength(80); grid.RowDefinitions.Add(row2); //设置ColumnDefinition ColumnDefinition col1 = new ColumnDefinition(); col1.Width = new GridLength(170); grid.ColumnDefinitions.Add(col1); ColumnDefinition col2 = new ColumnDefinition(); col2.Width = new GridLength(30); grid.ColumnDefinitions.Add(col2); //关闭按钮 Button b = new Button(); Thickness thickNess = new Thickness(0); b.BorderThickness = thickNess; b.Background = new SolidColorBrush(Colors.Red); b.Height = 20; b.Width = 30; b.HorizontalAlignment = HorizontalAlignment.Right; b.Content = "关闭"; b.Click += b_Click; b.MouseMove += b_MouseEnter; b.MouseLeave += b_MouseLeave; //将Button添加到Grid中 grid.Children.Add(b); //设置Button在Grid中的位置 b.SetValue(Grid.RowProperty, 0); b.SetValue(Grid.ColumnProperty, 1); //提醒框标题 TextBlock header = new TextBlock(); header.Text = "消息提醒"; header.FontSize = 13; header.FontWeight = FontWeights.Bold; header.Height = 20; header.Width = 170; //header.Foreground = new SolidColorBrush(Color.FromArgb(255, 0, 150, 255)); header.HorizontalAlignment = HorizontalAlignment.Center; thickNess = new Thickness(3, 2, 0, 0); header.Padding = thickNess; //将TextBlock添加到Grid中 grid.Children.Add(header); //设置TextBlock在Grid中的位置 header.SetValue(Grid.RowProperty, 0); header.SetValue(Grid.ColumnProperty, 0); //提醒内容 TextBlock txtContent = new TextBlock(); txtContent.FontSize = 12; txtContent.Name = "txtContent"; txtContent.Foreground = new SolidColorBrush(Color.FromArgb(255, 11, 77, 123)); thickNess = new Thickness(3, 3, 3, 3); txtContent.Padding = thickNess; txtContent.Cursor = Cursors.Hand; txtContent.TextWrapping = TextWrapping.Wrap; txtContent.SetValue(Grid.RowProperty, 1); txtContent.SetValue(Grid.ColumnProperty, 0); Grid.SetColumnSpan(txtContent, 2); grid.Children.Add(txtContent); //Binding Text System.Windows.Data.Binding textBind = new System.Windows.Data.Binding(); textBind.Path = new PropertyPath("DataContext.Message"); textBind.ElementName = "mainGrid"; txtContent.SetBinding(TextBlock.TextProperty, textBind); //增加导航功能 txtContent.MouseLeftButtonDown += txtContent_MouseLeftButtonDown; txtContent.MouseMove += txtContent_MouseMove; txtContent.MouseLeave += txtContent_MouseLeave; control.Content = grid; nw.Content = control; //nw.Show(10000); } public void AddMessage(WindowsMsg msg) { msgList.Add(msg); //如果是第一个消息就显示消息 if (msgList.Count == 1) { ShowMessage(); } } public void ShowMessage() { if (msgList.Count > 0) { WindowsMsg msg = msgList[0]; //找到显示消息的grid Grid grid = ((nw.Content as UserControl).Content as Grid); if (grid != null) { grid.DataContext = msg; nw.Show(30000);//30S } } } private void CloseMessage() { Grid grid = ((nw.Content as UserControl).Content as Grid); if (grid != null&&grid.DataContext!=null) { WindowsMsg msg = grid.DataContext as WindowsMsg; if (msg != null) { //从列表中移除 msgList.Remove(msg); } if (nw != null) { nw.Close(); } } } private void b_MouseLeave(object sender, MouseEventArgs e) { Button bon = sender as Button; if (bon != null) { bon.Background = new SolidColorBrush(Colors.Red); } } private void b_MouseEnter(object sender, MouseEventArgs e) { Button bon = sender as Button; if (bon != null) { //bon.Background = new SolidColorBrush(Colors.White); bon.BorderBrush = new SolidColorBrush(Colors.White); } } //关闭NotificationWindow窗体 private void b_Click(object sender, RoutedEventArgs e) { if (nw != null) { nw.Close(); } CloseMessage(); ShowMessage(); } private void txtContent_MouseMove(object sender, MouseEventArgs e) { TextBlock tb = (sender as TextBlock); if (tb != null) { tb.Cursor = Cursors.Hand; tb.Foreground = new SolidColorBrush(Color.FromArgb(255, 21, 121, 234)); } } private void txtContent_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { WindowsMsg notifyMsg = (sender as TextBlock).DataContext as WindowsMsg; string url = notifyMsg.PageUri; if (!string.IsNullOrWhiteSpace(url)) { Uri uri = new Uri(url, UriKind.Relative); //导航 EventAggregatorRepository.EventAggregator.GetEvent<NavigateEvent>().Publish(uri); } if (nw != null) { nw.Close(); } CloseMessage(); ShowMessage(); } private void txtContent_MouseLeave(object sender, MouseEventArgs e) { TextBlock tb = (sender as TextBlock); if (tb != null) { tb.Foreground = new SolidColorBrush(Color.FromArgb(255, 11, 77, 123)); } } }
代码:点我下载