Optimized growl

This commit is contained in:
NaBian committed 2019-03-31 21:42:05 +08:00
1 parent 513e57f013
commit f7ca63a1ca
10 files changed
+154 -76

No files matched your search

+104 -16
View File
@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
@@ -52,6 +53,8 @@ namespace HandyControl.Controls
/// </summary> /// </summary>
private DispatcherTimer _timerClose; private DispatcherTimer _timerClose;
private static readonly Dictionary<string, Panel> PanelDic = new Dictionary<string, Panel>();
#endregion Data #endregion Data
public Growl() public Growl()
@@ -61,6 +64,40 @@ namespace HandyControl.Controls
CommandBindings.Add(new CommandBinding(ControlCommands.Confirm, ButtonOk_OnClick)); 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) protected override void OnMouseEnter(MouseEventArgs e)
{ {
base.OnMouseEnter(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 void SetGrowlParent(DependencyObject element, bool value) => element.SetValue(GrowlParentProperty, value);
public static bool GetGrowlParent(DependencyObject element) => (bool)element.GetValue(GrowlParentProperty); public static bool GetGrowlParent(DependencyObject element) => (bool)element.GetValue(GrowlParentProperty);
@@ -214,18 +275,23 @@ namespace HandyControl.Controls
private static void SetGrowlPanel(Panel panel) private static void SetGrowlPanel(Panel panel)
{ {
GrowlPanel = panel; GrowlPanel = panel;
InitGrowlPanel(panel);
}
private static void InitGrowlPanel(Panel panel)
{
var menuItem = new MenuItem var menuItem = new MenuItem
{ {
Header = Properties.Langs.Lang.Clear Header = Properties.Langs.Lang.Clear
}; };
menuItem.Click += (s, e) => menuItem.Click += (s, e) =>
{ {
foreach (var item in GrowlPanel.Children.OfType<Growl>()) foreach (var item in panel.Children.OfType<Growl>())
{ {
item.Close(); item.Close();
} }
}; };
GrowlPanel.ContextMenu = new ContextMenu panel.ContextMenu = new ContextMenu
{ {
Items = Items =
{ {
@@ -233,7 +299,7 @@ namespace HandyControl.Controls
} }
}; };
PanelElement.SetFluidMoveBehavior(GrowlPanel, ResourceHelper.GetResource<FluidMoveBehavior>(ResourceToken.BehaviorXY400)); PanelElement.SetFluidMoveBehavior(panel, ResourceHelper.GetResource<FluidMoveBehavior>(ResourceToken.BehaviorXY400));
} }
private void Update() private void Update()
@@ -278,7 +344,17 @@ namespace HandyControl.Controls
Type = growlInfo.Type, Type = growlInfo.Type,
_waitTime = Math.Max(growlInfo.WaitTime, 2) _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
/// 成功 /// 成功
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
public static void Success(string message) => Success(new GrowlInfo /// <param name="token"></param>
public static void Success(string message, string token = "") => Success(new GrowlInfo
{ {
Message = message Message = message,
Token = token
}); });
/// <summary> /// <summary>
@@ -311,9 +389,11 @@ namespace HandyControl.Controls
/// 消息 /// 消息
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
public static void Info(string message) => Info(new GrowlInfo /// <param name="token"></param>
public static void Info(string message, string token = "") => Info(new GrowlInfo
{ {
Message = message Message = message,
Token = token
}); });
/// <summary> /// <summary>
@@ -336,9 +416,11 @@ namespace HandyControl.Controls
/// 警告 /// 警告
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
public static void Warning(string message) => Warning(new GrowlInfo /// <param name="token"></param>
public static void Warning(string message, string token = "") => Warning(new GrowlInfo
{ {
Message = message Message = message,
Token = token
}); });
/// <summary> /// <summary>
@@ -361,9 +443,11 @@ namespace HandyControl.Controls
/// 错误 /// 错误
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
public static void Error(string message) => Error(new GrowlInfo /// <param name="token"></param>
public static void Error(string message, string token = "") => Error(new GrowlInfo
{ {
Message = message Message = message,
Token = token
}); });
/// <summary> /// <summary>
@@ -387,9 +471,11 @@ namespace HandyControl.Controls
/// 严重 /// 严重
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
public static void Fatal(string message) => Fatal(new GrowlInfo /// <param name="token"></param>
public static void Fatal(string message, string token = "") => Fatal(new GrowlInfo
{ {
Message = message Message = message,
Token = token
}); });
/// <summary> /// <summary>
@@ -416,10 +502,12 @@ namespace HandyControl.Controls
/// </summary> /// </summary>
/// <param name="message"></param> /// <param name="message"></param>
/// <param name="actionBeforeClose"></param> /// <param name="actionBeforeClose"></param>
public static void Ask(string message, Func<bool, bool> actionBeforeClose) => Ask(new GrowlInfo /// <param name="token"></param>
public static void Ask(string message, Func<bool, bool> actionBeforeClose, string token = "") => Ask(new GrowlInfo
{ {
Message = message, Message = message,
ActionBeforeClose = actionBeforeClose ActionBeforeClose = actionBeforeClose,
Token = token
}); });
/// <summary> /// <summary>
+2
View File
@@ -27,5 +27,7 @@ namespace HandyControl.Data
public string IconBrushKey { get; set; } public string IconBrushKey { get; set; }
public bool ShowCloseButton { get; set; } = true; public bool ShowCloseButton { get; set; } = true;
public string Token { get; set; }
} }
} }
+2
View File
@@ -160,5 +160,7 @@
public static readonly string SendChatMessage = nameof(SendChatMessage); public static readonly string SendChatMessage = nameof(SendChatMessage);
public static readonly string GrowlDemoPanel = nameof(GrowlDemoPanel);
} }
} }
+3 -2
View File
@@ -45,7 +45,7 @@ var controlList = new List<string>
"TransferDemoCtl", "TransferDemoCtl",
"ChatBubbleDemoCtl", "ChatBubbleDemoCtl",
"GotoTopDemoCtl", "GotoTopDemoCtl",
"NotifyIconDemoCtl" "NotifyIconDemoCtl",
"BadgeDemoCtl", "BadgeDemoCtl",
"GravatarDemoCtl", "GravatarDemoCtl",
"DialogDemoCtl" "DialogDemoCtl"
@@ -91,7 +91,8 @@ var messageList = new List<string>
"FullSwitch", "FullSwitch",
"ContributorsView", "ContributorsView",
"ClearLeftSelected", "ClearLeftSelected",
"SendChatMessage" "SendChatMessage",
"GrowlDemoPanel"
}; };
#> #>
namespace HandyControlDemo.Data namespace HandyControlDemo.Data
+1 -1
View File
@@ -33,7 +33,7 @@
<userControl:MainContent Grid.Column="1"/> <userControl:MainContent Grid.Column="1"/>
<GridSplitter Grid.Column="1" HorizontalAlignment="Left" Width="4" Background="Transparent" BorderThickness="1,0,0,0" BorderBrush="{DynamicResource BorderBrush}"/> <GridSplitter Grid.Column="1" HorizontalAlignment="Left" Width="4" Background="Transparent" BorderThickness="1,0,0,0" BorderBrush="{DynamicResource BorderBrush}"/>
<controls:ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Right" IsEnableInertia="True" IsPenetrating="True"> <controls:ScrollViewer Grid.Column="1" VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Right" IsEnableInertia="True" IsPenetrating="True">
<StackPanel Name="GrowlPanel" VerticalAlignment="Top" Margin="0,10,10,10"/> <StackPanel controls:Growl.GrowlParent="True" VerticalAlignment="Top" Margin="0,10,10,10"/>
</controls:ScrollViewer> </controls:ScrollViewer>
</Grid> </Grid>
</controls:BlurWindow> </controls:BlurWindow>
+1 -16
View File
@@ -1,5 +1,4 @@
using System; using System.ComponentModel;
using System.ComponentModel;
using HandyControl.Controls; using HandyControl.Controls;
using HandyControlDemo.Data; using HandyControlDemo.Data;
@@ -12,20 +11,6 @@ namespace HandyControlDemo
InitializeComponent(); 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) protected override void OnClosing(CancelEventArgs e)
{ {
if (GlobalData.NotifyIconIsShow) if (GlobalData.NotifyIconIsShow)
@@ -8,11 +8,23 @@ namespace HandyControlDemo.ViewModel
{ {
public class GrowlDemoViewModel public class GrowlDemoViewModel
{ {
private readonly string _token;
public GrowlDemoViewModel()
{
}
public GrowlDemoViewModel(string token)
{
_token = token;
}
public RelayCommand InfoCmd => new Lazy<RelayCommand>(() => public RelayCommand InfoCmd => new Lazy<RelayCommand>(() =>
new RelayCommand(() => Growl.Info(Properties.Langs.Lang.GrowlInfo))).Value; new RelayCommand(() => Growl.Info(Properties.Langs.Lang.GrowlInfo, _token))).Value;
public RelayCommand SuccessCmd => new Lazy<RelayCommand>(() => public RelayCommand SuccessCmd => new Lazy<RelayCommand>(() =>
new RelayCommand(() => Growl.Success(Properties.Langs.Lang.GrowlSuccess))).Value; new RelayCommand(() => Growl.Success(Properties.Langs.Lang.GrowlSuccess, _token))).Value;
public RelayCommand WarningCmd => new Lazy<RelayCommand>(() => public RelayCommand WarningCmd => new Lazy<RelayCommand>(() =>
new RelayCommand(() => Growl.Warning(new GrowlInfo new RelayCommand(() => Growl.Warning(new GrowlInfo
@@ -23,24 +35,26 @@ namespace HandyControlDemo.ViewModel
{ {
Growl.Info(isConfirmed.ToString()); Growl.Info(isConfirmed.ToString());
return true; return true;
} },
Token = _token
}))).Value; }))).Value;
public RelayCommand ErrorCmd => new Lazy<RelayCommand>(() => public RelayCommand ErrorCmd => new Lazy<RelayCommand>(() =>
new RelayCommand(() => Growl.Error(Properties.Langs.Lang.GrowlError))).Value; new RelayCommand(() => Growl.Error(Properties.Langs.Lang.GrowlError, _token))).Value;
public RelayCommand AskCmd => new Lazy<RelayCommand>(() => public RelayCommand AskCmd => new Lazy<RelayCommand>(() =>
new RelayCommand(() => Growl.Ask(Properties.Langs.Lang.GrowlAsk, isConfirmed => new RelayCommand(() => Growl.Ask(Properties.Langs.Lang.GrowlAsk, isConfirmed =>
{ {
Growl.Info(isConfirmed.ToString()); Growl.Info(isConfirmed.ToString());
return true; return true;
}))).Value; }, _token))).Value;
public RelayCommand FatalCmd => new Lazy<RelayCommand>(() => public RelayCommand FatalCmd => new Lazy<RelayCommand>(() =>
new RelayCommand(() => Growl.Fatal(new GrowlInfo new RelayCommand(() => Growl.Fatal(new GrowlInfo
{ {
Message = Properties.Langs.Lang.GrowlFatal, Message = Properties.Langs.Lang.GrowlFatal,
ShowDateTime = false ShowDateTime = false,
Token = _token
}))).Value; }))).Value;
public RelayCommand ClearCmd => new Lazy<RelayCommand>(() => public RelayCommand ClearCmd => new Lazy<RelayCommand>(() =>
@@ -1,7 +1,9 @@
using System; using System;
using System.Reflection.Emit;
using System.Windows; using System.Windows;
using CommonServiceLocator; using CommonServiceLocator;
using GalaSoft.MvvmLight.Ioc; using GalaSoft.MvvmLight.Ioc;
using HandyControlDemo.Data;
using HandyControlDemo.Service; using HandyControlDemo.Service;
namespace HandyControlDemo.ViewModel namespace HandyControlDemo.ViewModel
@@ -15,7 +17,8 @@ namespace HandyControlDemo.ViewModel
SimpleIoc.Default.Register<DataService>(); SimpleIoc.Default.Register<DataService>();
SimpleIoc.Default.Register<MainViewModel>(); SimpleIoc.Default.Register<MainViewModel>();
SimpleIoc.Default.Register<GrowlDemoViewModel>(); SimpleIoc.Default.Register(() => new GrowlDemoViewModel(), "GrowlDemo");
SimpleIoc.Default.Register(() => new GrowlDemoViewModel(MessageToken.GrowlDemoPanel), "GrowlDemoWithToken");
SimpleIoc.Default.Register<ImageBrowserDemoViewModel>(); SimpleIoc.Default.Register<ImageBrowserDemoViewModel>();
SimpleIoc.Default.Register<ComboBoxDemoViewModel>(); SimpleIoc.Default.Register<ComboBoxDemoViewModel>();
SimpleIoc.Default.Register<WindowDemoViewModel>(); SimpleIoc.Default.Register<WindowDemoViewModel>();
@@ -36,7 +39,9 @@ namespace HandyControlDemo.ViewModel
public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>(); public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>();
public GrowlDemoViewModel GrowlDemo => ServiceLocator.Current.GetInstance<GrowlDemoViewModel>(); public GrowlDemoViewModel GrowlDemo => ServiceLocator.Current.GetInstance<GrowlDemoViewModel>("GrowlDemo");
public GrowlDemoViewModel GrowlDemoWithToken => ServiceLocator.Current.GetInstance<GrowlDemoViewModel>("GrowlDemoWithToken");
public ImageBrowserDemoViewModel ImageBrowserDemo => ServiceLocator.Current.GetInstance<ImageBrowserDemoViewModel>(); public ImageBrowserDemoViewModel ImageBrowserDemo => ServiceLocator.Current.GetInstance<ImageBrowserDemoViewModel>();
+13 -15
View File
@@ -3,26 +3,24 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl" xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs" 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}" Title="{x:Static langs:Lang.GrowlDemo}"
Width="800" Width="800"
Height="500"> Height="500">
<controls:TransitioningContentControl> <controls:TransitioningContentControl>
<controls:SimplePanel> <controls:SimplePanel Margin="32">
<StackPanel Margin="32"> <WrapPanel>
<WrapPanel HorizontalAlignment="Left" VerticalAlignment="Top"> <Button Command="{Binding InfoCmd}" Content="{x:Static langs:Lang.Info}" Margin="0,5,5,5" Style="{StaticResource ButtonInfo}"/>
<Button Command="{Binding InfoCmd}" Content="{x:Static langs:Lang.Info}" Margin="0,5,5,5" Style="{StaticResource ButtonInfo}"/> <Button Command="{Binding SuccessCmd}" Content="{x:Static langs:Lang.Success}" Margin="5" Style="{StaticResource ButtonSuccess}"/>
<Button Command="{Binding SuccessCmd}" Content="{x:Static langs:Lang.Success}" Margin="5" Style="{StaticResource ButtonSuccess}"/> <Button Command="{Binding WarningCmd}" Content="{x:Static langs:Lang.Warning}" Margin="5" Style="{StaticResource ButtonWarning}"/>
<Button Command="{Binding WarningCmd}" Content="{x:Static langs:Lang.Warning}" Margin="5" Style="{StaticResource ButtonWarning}"/> <Button Command="{Binding ErrorCmd}" Content="{x:Static langs:Lang.Error}" Margin="5" Style="{StaticResource ButtonDanger}"/>
<Button Command="{Binding ErrorCmd}" Content="{x:Static langs:Lang.Error}" Margin="5" Style="{StaticResource ButtonDanger}"/> <Button Command="{Binding AskCmd}" Content="{x:Static langs:Lang.Ask}" Margin="5" Background="BlueViolet" Foreground="White"/>
<Button Command="{Binding AskCmd}" Content="{x:Static langs:Lang.Ask}" Margin="5" Background="BlueViolet" Foreground="White"/> <Button Command="{Binding FatalCmd}" Content="{x:Static langs:Lang.Fatal}" Margin="5,0"/>
<Button Command="{Binding FatalCmd}" Content="{x:Static langs:Lang.Fatal}" Margin="5,0"/> <Button Command="{Binding ClearCmd}" Content="{x:Static langs:Lang.Clear}" Margin="5,0,0,0" Style="{StaticResource ButtonPrimary}"/>
<Button Command="{Binding ClearCmd}" Content="{x:Static langs:Lang.Clear}" Margin="5,0,0,0" Style="{StaticResource ButtonPrimary}"/> </WrapPanel>
</WrapPanel>
<Button Command="{Binding NewWindowCmd}" Content="{x:Static langs:Lang.NewWindow}" HorizontalAlignment="Left" Margin="0,5,0,0"/>
</StackPanel>
<controls:ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Right" IsEnableInertia="True" IsPenetrating="True"> <controls:ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalAlignment="Right" IsEnableInertia="True" IsPenetrating="True">
<StackPanel Name="GrowlPanel" VerticalAlignment="Top" Margin="0,10,10,10"/> <StackPanel controls:Growl.Token="{x:Static data:MessageToken.GrowlDemoPanel}" VerticalAlignment="Top" Margin="0,10,10,10"/>
</controls:ScrollViewer> </controls:ScrollViewer>
</controls:SimplePanel> </controls:SimplePanel>
</controls:TransitioningContentControl> </controls:TransitioningContentControl>
@@ -1,7 +1,4 @@
using System; namespace HandyControlDemo.Window
using HandyControl.Controls;
namespace HandyControlDemo.Window
{ {
public partial class GrowlDemoWindow public partial class GrowlDemoWindow
{ {
@@ -9,19 +6,5 @@ namespace HandyControlDemo.Window
{ {
InitializeComponent(); 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);
}
} }
} }