想在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); } }
完整代碼:
View Code
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)); } } }
代碼:點我下載
