From f7ca63a1ca3db52b76b5c40b6554c216e4f69930 Mon Sep 17 00:00:00 2001 From: NaBian <836904362@qq.com> Date: Sun, 31 Mar 2019 21:42:05 +0800 Subject: [PATCH] Optimized growl --- HandyControl/Controls/Other/Growl.cs | 120 +++++++++++++++--- HandyControl/Data/GrowlInfo.cs | 2 + HandyControlDemo/Data/MessageToken.cs | 4 +- HandyControlDemo/Data/MessageToken.tt | 5 +- HandyControlDemo/MainWindow.xaml | 2 +- HandyControlDemo/MainWindow.xaml.cs | 17 +-- .../ViewModel/Controls/GrowlDemoViewModel.cs | 26 +++- .../ViewModel/ViewModelLocator.cs | 9 +- HandyControlDemo/Window/GrowlDemoWindow.xaml | 28 ++-- .../Window/GrowlDemoWindow.xaml.cs | 19 +-- 10 files changed, 155 insertions(+), 77 deletions(-) diff --git a/HandyControl/Controls/Other/Growl.cs b/HandyControl/Controls/Other/Growl.cs index ed274460..b9523dbd 100644 --- a/HandyControl/Controls/Other/Growl.cs +++ b/HandyControl/Controls/Other/Growl.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; @@ -52,6 +53,8 @@ namespace HandyControl.Controls /// private DispatcherTimer _timerClose; + private static readonly Dictionary PanelDic = new Dictionary(); + #endregion Data public Growl() @@ -61,6 +64,40 @@ namespace HandyControl.Controls CommandBindings.Add(new CommandBinding(ControlCommands.Confirm, ButtonOk_OnClick)); } + public static void Register(string token, Panel panel) + { + if (string.IsNullOrEmpty(token) || panel == null) return; + PanelDic[token] = panel; + InitGrowlPanel(panel); + } + + public static void Unregister(string token, Panel panel) + { + if (string.IsNullOrEmpty(token) || panel == null) return; + + if (PanelDic.ContainsKey(token)) + { + if (ReferenceEquals(PanelDic[token], panel)) + { + PanelDic.Remove(token); + panel.ContextMenu = null; + panel.SetCurrentValue(PanelElement.FluidMoveBehaviorProperty, DependencyProperty.UnsetValue); + } + } + } + + public static void Unregister(Panel panel) + { + if (panel == null) return; + var first = PanelDic.FirstOrDefault(item => ReferenceEquals(panel, item.Value)); + if (!string.IsNullOrEmpty(first.Key)) + { + PanelDic.Remove(first.Key); + panel.ContextMenu = null; + panel.SetCurrentValue(PanelElement.FluidMoveBehaviorProperty, DependencyProperty.UnsetValue); + } + } + protected override void OnMouseEnter(MouseEventArgs e) { base.OnMouseEnter(e); @@ -132,6 +169,30 @@ namespace HandyControl.Controls } })); + public static readonly DependencyProperty TokenProperty = DependencyProperty.RegisterAttached( + "Token", typeof(string), typeof(Growl), new PropertyMetadata(default(string), OnTokenChanged)); + + private static void OnTokenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + if (d is Panel panel) + { + if (e.NewValue == null) + { + Unregister(panel); + } + else + { + Register(e.NewValue.ToString(), panel); + } + } + } + + public static void SetToken(DependencyObject element, string value) + => element.SetValue(TokenProperty, value); + + public static string GetToken(DependencyObject element) + => (string) element.GetValue(TokenProperty); + public static void SetGrowlParent(DependencyObject element, bool value) => element.SetValue(GrowlParentProperty, value); public static bool GetGrowlParent(DependencyObject element) => (bool)element.GetValue(GrowlParentProperty); @@ -214,18 +275,23 @@ namespace HandyControl.Controls private static void SetGrowlPanel(Panel panel) { GrowlPanel = panel; + InitGrowlPanel(panel); + } + + private static void InitGrowlPanel(Panel panel) + { var menuItem = new MenuItem { Header = Properties.Langs.Lang.Clear }; menuItem.Click += (s, e) => { - foreach (var item in GrowlPanel.Children.OfType()) + foreach (var item in panel.Children.OfType()) { item.Close(); } }; - GrowlPanel.ContextMenu = new ContextMenu + panel.ContextMenu = new ContextMenu { Items = { @@ -233,7 +299,7 @@ namespace HandyControl.Controls } }; - PanelElement.SetFluidMoveBehavior(GrowlPanel, ResourceHelper.GetResource(ResourceToken.BehaviorXY400)); + PanelElement.SetFluidMoveBehavior(panel, ResourceHelper.GetResource(ResourceToken.BehaviorXY400)); } private void Update() @@ -278,7 +344,17 @@ namespace HandyControl.Controls Type = growlInfo.Type, _waitTime = Math.Max(growlInfo.WaitTime, 2) }; - GrowlPanel.Children.Insert(0, ctl); + if (!string.IsNullOrEmpty(growlInfo.Token)) + { + if (PanelDic.TryGetValue(growlInfo.Token, out var panel)) + { + panel?.Children.Insert(0, ctl); + } + } + else + { + GrowlPanel.Children.Insert(0, ctl); + } }); } @@ -286,9 +362,11 @@ namespace HandyControl.Controls /// 成功 /// /// - public static void Success(string message) => Success(new GrowlInfo + /// + public static void Success(string message, string token = "") => Success(new GrowlInfo { - Message = message + Message = message, + Token = token }); /// @@ -311,9 +389,11 @@ namespace HandyControl.Controls /// 消息 /// /// - public static void Info(string message) => Info(new GrowlInfo + /// + public static void Info(string message, string token = "") => Info(new GrowlInfo { - Message = message + Message = message, + Token = token }); /// @@ -336,9 +416,11 @@ namespace HandyControl.Controls /// 警告 /// /// - public static void Warning(string message) => Warning(new GrowlInfo + /// + public static void Warning(string message, string token = "") => Warning(new GrowlInfo { - Message = message + Message = message, + Token = token }); /// @@ -361,9 +443,11 @@ namespace HandyControl.Controls /// 错误 /// /// - public static void Error(string message) => Error(new GrowlInfo + /// + public static void Error(string message, string token = "") => Error(new GrowlInfo { - Message = message + Message = message, + Token = token }); /// @@ -387,9 +471,11 @@ namespace HandyControl.Controls /// 严重 /// /// - public static void Fatal(string message) => Fatal(new GrowlInfo + /// + public static void Fatal(string message, string token = "") => Fatal(new GrowlInfo { - Message = message + Message = message, + Token = token }); /// @@ -416,10 +502,12 @@ namespace HandyControl.Controls /// /// /// - public static void Ask(string message, Func actionBeforeClose) => Ask(new GrowlInfo + /// + public static void Ask(string message, Func actionBeforeClose, string token = "") => Ask(new GrowlInfo { Message = message, - ActionBeforeClose = actionBeforeClose + ActionBeforeClose = actionBeforeClose, + Token = token }); /// diff --git a/HandyControl/Data/GrowlInfo.cs b/HandyControl/Data/GrowlInfo.cs index cffc7317..ef7d87f9 100644 --- a/HandyControl/Data/GrowlInfo.cs +++ b/HandyControl/Data/GrowlInfo.cs @@ -27,5 +27,7 @@ namespace HandyControl.Data public string IconBrushKey { get; set; } public bool ShowCloseButton { get; set; } = true; + + public string Token { get; set; } } } \ No newline at end of file diff --git a/HandyControlDemo/Data/MessageToken.cs b/HandyControlDemo/Data/MessageToken.cs index 6bf61c6e..588216c5 100644 --- a/HandyControlDemo/Data/MessageToken.cs +++ b/HandyControlDemo/Data/MessageToken.cs @@ -85,7 +85,7 @@ public static readonly string GotoTopDemoCtl = nameof(GotoTopDemoCtl); public static readonly string NotifyIconDemoCtl = nameof(NotifyIconDemoCtl); - + public static readonly string BadgeDemoCtl = nameof(BadgeDemoCtl); public static readonly string GravatarDemoCtl = nameof(GravatarDemoCtl); @@ -160,5 +160,7 @@ public static readonly string SendChatMessage = nameof(SendChatMessage); + public static readonly string GrowlDemoPanel = nameof(GrowlDemoPanel); + } } \ No newline at end of file diff --git a/HandyControlDemo/Data/MessageToken.tt b/HandyControlDemo/Data/MessageToken.tt index 149e30eb..dee74b06 100644 --- a/HandyControlDemo/Data/MessageToken.tt +++ b/HandyControlDemo/Data/MessageToken.tt @@ -45,7 +45,7 @@ var controlList = new List "TransferDemoCtl", "ChatBubbleDemoCtl", "GotoTopDemoCtl", - "NotifyIconDemoCtl" + "NotifyIconDemoCtl", "BadgeDemoCtl", "GravatarDemoCtl", "DialogDemoCtl" @@ -91,7 +91,8 @@ var messageList = new List "FullSwitch", "ContributorsView", "ClearLeftSelected", - "SendChatMessage" + "SendChatMessage", + "GrowlDemoPanel" }; #> namespace HandyControlDemo.Data diff --git a/HandyControlDemo/MainWindow.xaml b/HandyControlDemo/MainWindow.xaml index 85db7f43..99344426 100644 --- a/HandyControlDemo/MainWindow.xaml +++ b/HandyControlDemo/MainWindow.xaml @@ -33,7 +33,7 @@ - + \ No newline at end of file diff --git a/HandyControlDemo/MainWindow.xaml.cs b/HandyControlDemo/MainWindow.xaml.cs index f4ff06dc..bb90030a 100644 --- a/HandyControlDemo/MainWindow.xaml.cs +++ b/HandyControlDemo/MainWindow.xaml.cs @@ -1,5 +1,4 @@ -using System; -using System.ComponentModel; +using System.ComponentModel; using HandyControl.Controls; using HandyControlDemo.Data; @@ -12,20 +11,6 @@ namespace HandyControlDemo InitializeComponent(); } - protected override void OnActivated(EventArgs e) - { - base.OnActivated(e); - - Growl.SetGrowlParent(GrowlPanel, true); - } - - protected override void OnDeactivated(EventArgs e) - { - base.OnDeactivated(e); - - Growl.SetGrowlParent(GrowlPanel, false); - } - protected override void OnClosing(CancelEventArgs e) { if (GlobalData.NotifyIconIsShow) diff --git a/HandyControlDemo/ViewModel/Controls/GrowlDemoViewModel.cs b/HandyControlDemo/ViewModel/Controls/GrowlDemoViewModel.cs index 6c0ce412..4eed2a41 100644 --- a/HandyControlDemo/ViewModel/Controls/GrowlDemoViewModel.cs +++ b/HandyControlDemo/ViewModel/Controls/GrowlDemoViewModel.cs @@ -8,11 +8,23 @@ namespace HandyControlDemo.ViewModel { public class GrowlDemoViewModel { + private readonly string _token; + + public GrowlDemoViewModel() + { + + } + + public GrowlDemoViewModel(string token) + { + _token = token; + } + public RelayCommand InfoCmd => new Lazy(() => - new RelayCommand(() => Growl.Info(Properties.Langs.Lang.GrowlInfo))).Value; + new RelayCommand(() => Growl.Info(Properties.Langs.Lang.GrowlInfo, _token))).Value; public RelayCommand SuccessCmd => new Lazy(() => - new RelayCommand(() => Growl.Success(Properties.Langs.Lang.GrowlSuccess))).Value; + new RelayCommand(() => Growl.Success(Properties.Langs.Lang.GrowlSuccess, _token))).Value; public RelayCommand WarningCmd => new Lazy(() => new RelayCommand(() => Growl.Warning(new GrowlInfo @@ -23,24 +35,26 @@ namespace HandyControlDemo.ViewModel { Growl.Info(isConfirmed.ToString()); return true; - } + }, + Token = _token }))).Value; public RelayCommand ErrorCmd => new Lazy(() => - new RelayCommand(() => Growl.Error(Properties.Langs.Lang.GrowlError))).Value; + new RelayCommand(() => Growl.Error(Properties.Langs.Lang.GrowlError, _token))).Value; public RelayCommand AskCmd => new Lazy(() => new RelayCommand(() => Growl.Ask(Properties.Langs.Lang.GrowlAsk, isConfirmed => { Growl.Info(isConfirmed.ToString()); return true; - }))).Value; + }, _token))).Value; public RelayCommand FatalCmd => new Lazy(() => new RelayCommand(() => Growl.Fatal(new GrowlInfo { Message = Properties.Langs.Lang.GrowlFatal, - ShowDateTime = false + ShowDateTime = false, + Token = _token }))).Value; public RelayCommand ClearCmd => new Lazy(() => diff --git a/HandyControlDemo/ViewModel/ViewModelLocator.cs b/HandyControlDemo/ViewModel/ViewModelLocator.cs index 1627d565..c6089cd3 100644 --- a/HandyControlDemo/ViewModel/ViewModelLocator.cs +++ b/HandyControlDemo/ViewModel/ViewModelLocator.cs @@ -1,7 +1,9 @@ using System; +using System.Reflection.Emit; using System.Windows; using CommonServiceLocator; using GalaSoft.MvvmLight.Ioc; +using HandyControlDemo.Data; using HandyControlDemo.Service; namespace HandyControlDemo.ViewModel @@ -15,7 +17,8 @@ namespace HandyControlDemo.ViewModel SimpleIoc.Default.Register(); SimpleIoc.Default.Register(); - SimpleIoc.Default.Register(); + SimpleIoc.Default.Register(() => new GrowlDemoViewModel(), "GrowlDemo"); + SimpleIoc.Default.Register(() => new GrowlDemoViewModel(MessageToken.GrowlDemoPanel), "GrowlDemoWithToken"); SimpleIoc.Default.Register(); SimpleIoc.Default.Register(); SimpleIoc.Default.Register(); @@ -36,7 +39,9 @@ namespace HandyControlDemo.ViewModel public MainViewModel Main => ServiceLocator.Current.GetInstance(); - public GrowlDemoViewModel GrowlDemo => ServiceLocator.Current.GetInstance(); + public GrowlDemoViewModel GrowlDemo => ServiceLocator.Current.GetInstance("GrowlDemo"); + + public GrowlDemoViewModel GrowlDemoWithToken => ServiceLocator.Current.GetInstance("GrowlDemoWithToken"); public ImageBrowserDemoViewModel ImageBrowserDemo => ServiceLocator.Current.GetInstance(); diff --git a/HandyControlDemo/Window/GrowlDemoWindow.xaml b/HandyControlDemo/Window/GrowlDemoWindow.xaml index c77f86a7..acee9654 100644 --- a/HandyControlDemo/Window/GrowlDemoWindow.xaml +++ b/HandyControlDemo/Window/GrowlDemoWindow.xaml @@ -3,26 +3,24 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl" xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs" - DataContext="{Binding GrowlDemo,Source={StaticResource Locator}}" + xmlns:data="clr-namespace:HandyControlDemo.Data" + DataContext="{Binding GrowlDemoWithToken,Source={StaticResource Locator}}" Title="{x:Static langs:Lang.GrowlDemo}" Width="800" Height="500"> - - - -