private async Task ShowAsync(Banner banner, BannerMessageQueueItem messageQueueItem, ManualResetEvent actionClickWaitHandle) { //create and show the message, setting up all the handles we need to wait on var tuple = CreateAndShowMessage(banner, messageQueueItem, actionClickWaitHandle); var bannerMessage = tuple.Item1; var mouseNotOverManagedWaitHandle = tuple.Item2; var durationPassedWaitHandle = new ManualResetEvent(false); StartDuration(messageQueueItem.Duration.Add(banner.ActivateStoryboardDuration), durationPassedWaitHandle); //wait until time span completed (including pauses and mouse overs), or the action is clicked await WaitForCompletionAsync(mouseNotOverManagedWaitHandle, durationPassedWaitHandle, actionClickWaitHandle); //close message on banner banner.SetCurrentValue(Banner.IsActiveProperty, false); //we could wait for the animation event, but just doing //this for now...at least it is prevent extra call back hell await Task.Delay(banner.DeactivateStoryboardDuration); //this prevents missing resource warnings after the message is removed from the Banner //see https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/issues/2040 bannerMessage.Resources = BannerMessage.defaultResources; //remove message on banner banner.SetCurrentValue(Banner.MessageProperty, null); mouseNotOverManagedWaitHandle.Dispose(); durationPassedWaitHandle.Dispose(); }
private void InsertItem(BannerMessageQueueItem item) { lock (_bannerMessagesLock) { var added = false; var node = _bannerMessages.First; while (node != null) { if (!IgnoreDuplicate && item.IsDuplicate(node.Value)) { return; } if (item.IsPromoted && !node.Value.IsPromoted) { _bannerMessages.AddBefore(node, item); added = true; break; } node = node.Next; } if (!added) { _bannerMessages.AddLast(item); } } _dispatcher.InvokeAsync(ShowNextAsync); }
/// <summary> /// Checks if given item is a duplicate to this /// </summary> /// <param name="item">Item to check for duplicate</param> /// <returns><c>true</c> if given item is a duplicate to this, <c>false</c> otherwise</returns> public bool IsDuplicate(BannerMessageQueueItem item) { if (item is null) { throw new ArgumentNullException(nameof(item)); } return(!IgnoreDuplicate && Equals(item.Content, Content) && Equals(item.ActionContent, ActionContent)); }
private static void DoActionCallback(BannerMessageQueueItem messageQueueItem) { try { messageQueueItem.ActionHandler?.Invoke(messageQueueItem.ActionArgument); } catch (Exception exc) { Trace.WriteLine("Error during BannerMessageQueue message action callback, exception will be rethrown."); Trace.WriteLine($"{exc.Message} ({exc.GetType().FullName})"); Trace.WriteLine(exc.StackTrace); throw; } }
public void Enqueue(object content, object?actionContent, Action <object?>?actionHandler, object?actionArgument, bool promote, bool neverConsiderToBeDuplicate, TimeSpan?durationOverride = null) { if (content is null) { throw new ArgumentNullException(nameof(content)); } if (actionContent is null ^ actionHandler is null) { throw new ArgumentException("All action arguments must be provided if any are provided.", actionContent != null ? nameof(actionContent) : nameof(actionHandler)); } var bannerMessageQueueItem = new BannerMessageQueueItem(content, durationOverride ?? _messageDuration, actionContent, actionHandler, actionArgument, promote, neverConsiderToBeDuplicate); InsertItem(bannerMessageQueueItem); }
private static Tuple <BannerMessage, MouseNotOverManagedWaitHandle> CreateAndShowMessage(UIElement banner, BannerMessageQueueItem messageQueueItem, EventWaitHandle actionClickWaitHandle) { var clickCount = 0; var bannerMessage = new BannerMessage { Content = messageQueueItem.Content, ActionContent = messageQueueItem.ActionContent }; bannerMessage.ActionClick += (sender, args) => { if (++clickCount == 1) { DoActionCallback(messageQueueItem); } actionClickWaitHandle.Set(); }; banner.SetCurrentValue(Banner.MessageProperty, bannerMessage); banner.SetCurrentValue(Banner.IsActiveProperty, true); return(Tuple.Create(bannerMessage, new MouseNotOverManagedWaitHandle(banner))); }