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

 代碼:點我下載


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM