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);
            }
        }

 

完整代码:

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));
            }
        }
    }

 代码:点我下载

posted @ 2012-12-21 10:40  Gyoung  阅读(2826)  评论(4编辑  收藏  举报