upgraded growl

This commit is contained in:
NaBian committed 2019-08-02 00:15:06 +08:00
1 parent b6963d2770
commit 0061b04b71
17 files changed
+391 -174

No files matched your search

@@ -31,6 +31,8 @@ namespace HandyControl.Controls
#region Data
private static GrowlWindow GrowlWindow;
private Panel _panelMore;
private Grid _gridMain;
@@ -293,6 +295,8 @@ namespace HandyControl.Controls
private static void InitGrowlPanel(Panel panel)
{
if (panel == null) return;
var menuItem = new MenuItem
{
Header = Properties.Langs.Lang.Clear
@@ -334,6 +338,61 @@ namespace HandyControl.Controls
if (!_staysOpen) StartTimer();
}
private static void ShowGlobal(GrowlInfo growlInfo)
{
if (GrowlWindow == null)
{
GrowlWindow = new GrowlWindow();
GrowlWindow.Show();
InitGrowlPanel(GrowlWindow.GrowlPanel);
GrowlWindow.Init();
}
GrowlWindow.Show(true);
#if netle40
Application.Current.Dispatcher?.Invoke(new Action(() =>
{
var ctl = new Growl
{
Message = growlInfo.Message,
Time = DateTime.Now,
Icon = ResourceHelper.GetResource<Geometry>(growlInfo.IconKey),
IconBrush = ResourceHelper.GetResource<Brush>(growlInfo.IconBrushKey),
_showCloseButton = growlInfo.ShowCloseButton,
ActionBeforeClose = growlInfo.ActionBeforeClose,
_staysOpen = growlInfo.StaysOpen,
ShowDateTime = growlInfo.ShowDateTime,
ConfirmStr = growlInfo.ConfirmStr,
CancelStr = growlInfo.CancelStr,
Type = growlInfo.Type,
_waitTime = Math.Max(growlInfo.WaitTime, 2)
};
GrowlWindow.GrowlPanel.Children.Insert(0, ctl);
}));
#else
Application.Current.Dispatcher?.Invoke(() =>
{
var ctl = new Growl
{
Message = growlInfo.Message,
Time = DateTime.Now,
Icon = ResourceHelper.GetResource<Geometry>(growlInfo.IconKey),
IconBrush = ResourceHelper.GetResource<Brush>(growlInfo.IconBrushKey),
_showCloseButton = growlInfo.ShowCloseButton,
ActionBeforeClose = growlInfo.ActionBeforeClose,
_staysOpen = growlInfo.StaysOpen,
ShowDateTime = growlInfo.ShowDateTime,
ConfirmStr = growlInfo.ConfirmStr,
CancelStr = growlInfo.CancelStr,
Type = growlInfo.Type,
_waitTime = Math.Max(growlInfo.WaitTime, 2)
};
GrowlWindow.GrowlPanel.Children.Insert(0, ctl);
});
#endif
}
/// <summary>
/// 显示信息
/// </summary>
@@ -341,7 +400,7 @@ namespace HandyControl.Controls
private static void Show(GrowlInfo growlInfo)
{
#if netle40
Application.Current.Dispatcher.Invoke(new Action(() =>
Application.Current.Dispatcher?.Invoke(new Action(() =>
{
var ctl = new Growl
{
@@ -371,7 +430,7 @@ namespace HandyControl.Controls
}
}));
#else
Application.Current.Dispatcher.Invoke(() =>
Application.Current.Dispatcher?.Invoke(() =>
{
var ctl = new Growl
{
@@ -430,6 +489,31 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 成功
/// </summary>
/// <param name="message"></param>
public static void SuccessGlobal(string message) => SuccessGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 成功
/// </summary>
/// <param name="growlInfo"></param>
public static void SuccessGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.SuccessGeometry;
growlInfo.IconBrushKey = ResourceToken.SuccessBrush;
growlInfo.Type = InfoType.Success;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 消息
/// </summary>
@@ -457,6 +541,31 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 消息
/// </summary>
/// <param name="message"></param>
public static void InfoGlobal(string message) => InfoGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 消息
/// </summary>
/// <param name="growlInfo"></param>
public static void InfoGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.InfoGeometry;
growlInfo.IconBrushKey = ResourceToken.InfoBrush;
growlInfo.Type = InfoType.Info;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 警告
/// </summary>
@@ -484,6 +593,31 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 警告
/// </summary>
/// <param name="message"></param>
public static void WarningGlobal(string message) => WarningGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 警告
/// </summary>
/// <param name="growlInfo"></param>
public static void WarningGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.WarningGeometry;
growlInfo.IconBrushKey = ResourceToken.WarningBrush;
growlInfo.Type = InfoType.Warning;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 错误
/// </summary>
@@ -512,6 +646,32 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 错误
/// </summary>
/// <param name="message"></param>
public static void ErrorGlobal(string message) => ErrorGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 错误
/// </summary>
/// <param name="growlInfo"></param>
public static void ErrorGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.ErrorGeometry;
growlInfo.IconBrushKey = ResourceToken.DangerBrush;
growlInfo.StaysOpen = true;
growlInfo.Type = InfoType.Error;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 严重
/// </summary>
@@ -542,6 +702,34 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 严重
/// </summary>
/// <param name="message"></param>
public static void FatalGlobal(string message) => FatalGlobal(new GrowlInfo
{
Message = message
});
/// <summary>
/// 严重
/// </summary>
/// <param name="growlInfo"></param>
public static void FatalGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.FatalGeometry;
growlInfo.IconBrushKey = ResourceToken.PrimaryTextBrush;
growlInfo.StaysOpen = true;
growlInfo.ShowCloseButton = false;
growlInfo.Type = InfoType.Fatal;
if (GrowlPanel.ContextMenu != null) GrowlPanel.ContextMenu.Opacity = 0;
}
ShowGlobal(growlInfo);
}
/// <summary>
/// 询问
/// </summary>
@@ -573,6 +761,35 @@ namespace HandyControl.Controls
Show(growlInfo);
}
/// <summary>
/// 询问
/// </summary>
/// <param name="message"></param>
/// <param name="actionBeforeClose"></param>
public static void AskGlobal(string message, Func<bool, bool> actionBeforeClose) => AskGlobal(new GrowlInfo
{
Message = message,
ActionBeforeClose = actionBeforeClose
});
/// <summary>
/// 询问
/// </summary>
/// <param name="growlInfo"></param>
public static void AskGlobal(GrowlInfo growlInfo)
{
if (growlInfo == null) throw new ArgumentNullException(nameof(growlInfo));
if (!growlInfo.IsCustom)
{
growlInfo.IconKey = ResourceToken.AskGeometry;
growlInfo.IconBrushKey = ResourceToken.AccentBrush;
growlInfo.StaysOpen = true;
growlInfo.ShowCloseButton = false;
growlInfo.Type = InfoType.Ask;
}
ShowGlobal(growlInfo);
}
private void ButtonClose_OnClick(object sender, RoutedEventArgs e) => Close();
/// <summary>
@@ -589,6 +806,12 @@ namespace HandyControl.Controls
if (Parent is Panel panel)
{
panel.Children.Remove(this);
if (GrowlWindow?.GrowlPanel != null && GrowlWindow.GrowlPanel.Children.Count == 0)
{
GrowlWindow.Close();
GrowlWindow = null;
}
}
};
transform.BeginAnimation(TranslateTransform.XProperty, animation);
@@ -619,6 +842,7 @@ namespace HandyControl.Controls
/// <param name="panel"></param>
private static void Clear(Panel panel)
{
if (panel == null) return;
panel.Children.Clear();
if (panel.ContextMenu != null)
{
@@ -627,6 +851,17 @@ namespace HandyControl.Controls
}
}
/// <summary>
/// 清除
/// </summary>
public static void ClearGlobal()
{
if (GrowlWindow == null) return;
Clear(GrowlWindow.GrowlPanel);
GrowlWindow.Close();
GrowlWindow = null;
}
private void ButtonCancel_OnClick(object sender, RoutedEventArgs e)
{
if (ActionBeforeClose?.Invoke(false) == true)
@@ -0,0 +1,47 @@
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interop;
using HandyControl.Tools.Interop;
namespace HandyControl.Controls
{
[TemplatePart(Name = ElementGrowPanel, Type = typeof(Panel))]
internal class GrowlWindow : Window
{
private const string ElementGrowPanel = "PART_GrowPanel";
public Panel GrowlPanel { get; set; }
public GrowlWindow()
{
WindowStyle = WindowStyle.None;
AllowsTransparency = true;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
GrowlPanel = GetTemplateChild(ElementGrowPanel) as Panel;
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
var _ = new WindowInteropHelper(this)
{
Owner = NativeMethods.GetDesktopWindow()
};
}
public void Init()
{
var desktopWorkingArea = SystemParameters.WorkArea;
Height = desktopWorkingArea.Height;
Left = desktopWorkingArea.Right - Width;
Top = 0;
}
}
}
@@ -19,6 +19,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\PanelElement.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\PasswordBoxAttach.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Attach\RectangleAttach.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Growl\GrowlWindow.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Image\ImageBlock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Magnifier.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ButtonGroup.cs" />
@@ -83,7 +84,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Dialog.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\GotoTop.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Gravatar.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Growl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Growl\Growl.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\NotifyIcon.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Pagination.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ScrollViewer.cs" />
@@ -387,6 +388,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Growl.xaml">
<SubType>Designer</SubType>
<Generator>XamlIntelliSenseFileGenerator</Generator>
</Page>
<Page Include="$(MSBuildThisFileDirectory)Themes\Styles\Menu.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
@@ -812,4 +817,7 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="$(MSBuildThisFileDirectory)Controls\Growl\" />
</ItemGroup>
</Project>
@@ -0,0 +1,80 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:controls="clr-namespace:HandyControl.Controls"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Basic/Converters.xaml"/>
<ResourceDictionary Source="../Basic/Geometries.xaml"/>
<ResourceDictionary Source="../Basic/Effects.xaml"/>
<ResourceDictionary Source="TextBlock.xaml"/>
<ResourceDictionary Source="Button.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="controls:GrowlWindow">
<Setter Property="Width" Value="340"/>
<Setter Property="MaxWidth" Value="340"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="ShowActivated" Value="False"/>
<Setter Property="ShowInTaskbar" Value="False"/>
<Setter Property="Topmost" Value="True"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:GrowlWindow">
<controls:ScrollViewer VerticalScrollBarVisibility="Hidden" IsEnableInertia="True">
<StackPanel Name="PART_GrowPanel" VerticalAlignment="Top" Margin="0,10,10,10"/>
</controls:ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="controls:Growl">
<Setter Property="Focusable" Value="False"/>
<Setter Property="MinHeight" Value="60"/>
<Setter Property="Width" Value="320"/>
<Setter Property="Margin" Value="10,0,0,10"/>
<Setter Property="MaxWidth" Value="320"/>
<Setter Property="controls:BorderElement.CornerRadius" Value="8"/>
<Setter Property="Background" Value="{DynamicResource ThirdlyRegionBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:Growl">
<Grid Name="PART_GridMain" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<TransformGroup>
<TranslateTransform X="{TemplateBinding MaxWidth}"/>
</TransformGroup>
</Grid.RenderTransform>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Border Grid.ColumnSpan="3" Grid.RowSpan="2" Effect="{StaticResource EffectShadow2}" Background="{TemplateBinding Background}" CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" Width="320"/>
<Path Grid.Row="0" Grid.Column="0" VerticalAlignment="Top" Margin="0,15,0,0" Width="30" Height="30" Data="{TemplateBinding Icon}" Stretch="Uniform" Fill="{TemplateBinding IconBrush}"/>
<StackPanel VerticalAlignment="Center" Grid.Row="0" Grid.Column="1" Margin="0,10,10,10">
<TextBlock Text="{TemplateBinding Message}" Style="{StaticResource TextBlockDefault}" HorizontalAlignment="Left" TextWrapping="Wrap"/>
<TextBlock Visibility="{Binding ShowDateTime,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}" Text="{Binding Time,RelativeSource={RelativeSource AncestorType=controls:Growl},StringFormat=yyyy/MM/dd HH:mm:ss}" Style="{StaticResource TextBlockDefault}" Foreground="{DynamicResource SecondaryTextBrush}" HorizontalAlignment="Left" Margin="0,4,0,0"/>
</StackPanel>
<Button Grid.Row="0" Visibility="Collapsed" Margin="11,0" Name="PART_ButtonClose" Command="interactivity:ControlCommands.Close" Grid.Column="2" Background="Transparent" Style="{StaticResource ButtonCustom}" VerticalAlignment="Center" HorizontalAlignment="Center" Width="18" Height="18">
<Path Data="{StaticResource ErrorGeometry}" Stretch="Uniform" Fill="{DynamicResource SecondaryTextBrush}"/>
</Button>
<StackPanel Name="PART_PanelMore" IsEnabled="False" Visibility="Collapsed" Orientation="Horizontal" Grid.Row="1" Grid.ColumnSpan="3" Height="28" Grid.Column="0">
<Button Command="interactivity:ControlCommands.Cancel" Style="{StaticResource ButtonCustom}" Width="160">
<TextBlock Text="{Binding CancelStr,RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" Foreground="{DynamicResource DangerBrush}"/>
</Button>
<Button Command="interactivity:ControlCommands.Confirm" Style="{StaticResource ButtonCustom}" Width="160">
<TextBlock Text="{Binding ConfirmStr,RelativeSource={RelativeSource TemplatedParent}}" HorizontalAlignment="Center" Foreground="{DynamicResource PrimaryBrush}"/>
</Button>
</StackPanel>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -64,7 +64,8 @@ namespace HandyControl.Tools.Interop
LOGPIXELSX = 88,
LOGPIXELSY = 90,
CXFRAME = 32,
CXSIZEFRAME = CXFRAME;
CXSIZEFRAME = CXFRAME,
SW_HIDE = 0;
[Flags]
public enum ProcessAccess
@@ -219,5 +220,8 @@ namespace HandyControl.Tools.Interop
[SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
[DllImport(ExternDll.User32)]
public static extern int GetSystemMetrics(SM nIndex);
[DllImport(ExternDll.User32)]
public static extern IntPtr GetDesktopWindow();
}
}