Как открыть несколько windows в очереди, каждое окно ожидает закрытия предыдущего? - PullRequest
0 голосов
/ 14 февраля 2020

Я пытаюсь создать примитивную систему уведомлений.

Вот как я показываю свое окно:

var data = new NotificationData {
    Title = "New order",
    OrderId = "1"
}
var notification = new NotificationWindow(data);
    Activated += (s, e) => { notification.Owner = this; };
    notification.Show();

Тогда NotificationWindow просто отображает предоставленные данные. Но если есть несколько уведомлений, они все складываются в одном месте, мне нужно, чтобы они появлялись после закрытия предыдущего.

Я попытался использовать ShowDialog() вместо этого, и это сработало - но MainWindow зависает, когда Уведомление открыто. Запуск его в другом потоке с использованием Task.Run() приводит к тому, что уведомления не отображаются.

1 Ответ

5 голосов
/ 14 февраля 2020

Вам необходимо зарегистрироваться на закрытое событие, а затем проверить, находится ли другое уведомление в очереди.

Ключ - ShowOrQueueNotification, который проверяет, присутствует ли уведомление или нет. Если есть один подарок, поставьте в очередь новый и, когда уведомление закрыто, вам нужно проверить, есть ли один в очереди.

Я сделал пример, чтобы показать, как использовать для него очередь:


MainWindow.xaml

<Window x:Class="TestNotificationQueue.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestNotificationQueue"
        mc:Ignorable="d"
        Title="MainWindow" Height="158.868" Width="266.385">
    <Grid>
        <Border Background="Yellow" VerticalAlignment="Center" HorizontalAlignment="Center" BorderThickness="1" BorderBrush="Black" >
            <StackPanel Margin="20">
                <TextBox x:Name="TextBoxMessage" Width="192" />
                <Button Content="ShowNotification" Width="128" Height="24" Click="Button_Click" Margin="8"/>
            </StackPanel>
        </Border>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Windows;

namespace TestNotificationQueue
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private Queue<NotificationInfo> _notificationQueue = new Queue<NotificationInfo>();
        private NotificationWindow _currentNotificationWindow;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            ShowOrQueueNotification(new NotificationInfo(TextBoxMessage.Text));
        }

        private void ShowOrQueueNotification(NotificationInfo notificationInfo)
        {
// ----->   If no notification is presented, create one.
            if (_currentNotificationWindow == null)
            {
                _currentNotificationWindow = new NotificationWindow(notificationInfo);
                _currentNotificationWindow.Closed += CurrentNotificationWindow_Closed;
                _currentNotificationWindow.Show();
            }
            else
// ----->       queue it.
                _notificationQueue.Enqueue(notificationInfo);
        }

        private void CurrentNotificationWindow_Closed(object sender, EventArgs e)
        {
// ----->   This is crucial, you need to set the current to null, else all new notification will be queued and never be presented.
            _currentNotificationWindow = null;

            if(_notificationQueue.Count > 0)
                ShowOrQueueNotification(_notificationQueue.Dequeue());
        }
    }
}

Notification.cs

namespace TestNotificationQueue
{
    public class NotificationInfo
    {
        public NotificationInfo(string message)
        {
            Message = message;
        }

        public string Message { get; }
    }
}

NotificationWindow.xaml

<Window x:Class="TestNotificationQueue.NotificationWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:TestNotificationQueue"
        mc:Ignorable="d"
        Title="NotificationWindow" Height="93.117" Width="239.4">
    <Grid>
        <TextBlock x:Name="TextBoxMessage" HorizontalAlignment="Center" VerticalAlignment="Center" Width="200" Height="30" />
    </Grid>
</Window>

NotificationWindow.xaml .cs

using System.Windows;

namespace TestNotificationQueue
{
    /// <summary>
    /// Interaction logic for NotificationWindow.xaml
    /// </summary>
    public partial class NotificationWindow : Window
    {
        public NotificationWindow(NotificationInfo notificationInfo)
        {
            InitializeComponent();
            TextBoxMessage.Text = notificationInfo.Message;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...