enhance: Growl demo.

This commit is contained in:
NaBian committed 2025-09-08 23:20:47 +08:00
1 parent 8405e7f2b1
commit 83fc434e7d
5 files changed
+168 -71

No files matched your search

+3 -2
View File
@@ -2,12 +2,12 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:viewModel="clr-namespace:HandyControlDemo.ViewModel"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:d1P1="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:data="clr-namespace:HandyControlDemo.Data"
xmlns:hc="https://handyorg.github.io/handycontrol"
xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs"
d1P1:Ignorable="d"
d1P1:Ignorable="d"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
@@ -30,6 +30,7 @@
<hc:EnumDataProvider x:Key="DemoTypes" Type="data:DemoType"/>
<hc:EnumDataProvider x:Key="ShowAnimations" Type="hc:ShowAnimation"/>
<hc:EnumDataProvider x:Key="HatchStyles" Type="hc:HatchStyle"/>
<hc:EnumDataProvider x:Key="TransitionModes" Type="hc:TransitionMode"/>
</ResourceDictionary>
</Application.Resources>
</Application>
@@ -7,30 +7,82 @@
DataContext="{Binding GrowlDemo,Source={StaticResource Locator}}"
Background="{DynamicResource RegionBrush}">
<hc:TransitioningContentControl>
<StackPanel Margin="32">
<GroupBox Header="Window" Padding="10,5">
<hc:UniformSpacingPanel Margin="32"
Orientation="Vertical"
Spacing="32">
<ComboBox SelectedValue="{Binding TransitionMode}"
ItemsSource="{Binding Source={StaticResource TransitionModes}}" />
<GroupBox Header="Window"
Padding="10,5">
<WrapPanel VerticalAlignment="Center">
<Button Command="{Binding InfoCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Info}}" Margin="0,5,5,5" Style="{StaticResource ButtonInfo}"/>
<Button Command="{Binding SuccessCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Success}}" Margin="5" Style="{StaticResource ButtonSuccess}"/>
<Button Command="{Binding WarningCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Warning}}" Margin="5" Style="{StaticResource ButtonWarning}"/>
<Button Command="{Binding ErrorCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Error}}" Margin="5" Style="{StaticResource ButtonDanger}"/>
<Button Command="{Binding AskCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Ask}}" Margin="5" Background="BlueViolet" Foreground="White" BorderThickness="0"/>
<Button Command="{Binding FatalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Fatal}}" Margin="5,0"/>
<Button Command="{Binding ClearCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Clear}}" Margin="5,0,0,0" Style="{StaticResource ButtonPrimary}"/>
<Button Command="{Binding InfoCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Info}}"
Margin="0,5,5,5"
Style="{StaticResource ButtonInfo}" />
<Button Command="{Binding SuccessCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Success}}"
Margin="5"
Style="{StaticResource ButtonSuccess}" />
<Button Command="{Binding WarningCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Warning}}"
Margin="5"
Style="{StaticResource ButtonWarning}" />
<Button Command="{Binding ErrorCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Error}}"
Margin="5"
Style="{StaticResource ButtonDanger}" />
<Button Command="{Binding AskCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Ask}}"
Margin="5"
Background="BlueViolet"
Foreground="White"
BorderThickness="0" />
<Button Command="{Binding FatalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Fatal}}"
Margin="5,0" />
<Button Command="{Binding ClearCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Clear}}"
Margin="5,0,0,0"
Style="{StaticResource ButtonPrimary}" />
</WrapPanel>
</GroupBox>
<Button Command="{Binding NewWindowCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.NewWindow}}" Margin="0,32" HorizontalAlignment="Left"/>
<GroupBox Header="Desktop" Padding="10,5">
<Button Command="{Binding NewWindowCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.NewWindow}}"
HorizontalAlignment="Left" />
<GroupBox Header="Desktop"
Padding="10,5">
<WrapPanel VerticalAlignment="Center">
<Button Command="{Binding InfoGlobalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Info}}" Margin="0,5,5,5" Style="{StaticResource ButtonInfo}"/>
<Button Command="{Binding SuccessGlobalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Success}}" Margin="5" Style="{StaticResource ButtonSuccess}"/>
<Button Command="{Binding WarningGlobalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Warning}}" Margin="5" Style="{StaticResource ButtonWarning}"/>
<Button Command="{Binding ErrorGlobalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Error}}" Margin="5" Style="{StaticResource ButtonDanger}"/>
<Button Command="{Binding AskGlobalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Ask}}" Margin="5" Background="BlueViolet" Foreground="White" BorderThickness="0"/>
<Button Command="{Binding FatalGlobalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Fatal}}" Margin="5,0"/>
<Button Command="{Binding ClearGlobalCmd}" Content="{ex:Lang Key={x:Static langs:LangKeys.Clear}}" Margin="5,0,0,0" Style="{StaticResource ButtonPrimary}"/>
<Button Command="{Binding InfoGlobalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Info}}"
Margin="0,5,5,5"
Style="{StaticResource ButtonInfo}" />
<Button Command="{Binding SuccessGlobalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Success}}"
Margin="5"
Style="{StaticResource ButtonSuccess}" />
<Button Command="{Binding WarningGlobalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Warning}}"
Margin="5"
Style="{StaticResource ButtonWarning}" />
<Button Command="{Binding ErrorGlobalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Error}}"
Margin="5"
Style="{StaticResource ButtonDanger}" />
<Button Command="{Binding AskGlobalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Ask}}"
Margin="5"
Background="BlueViolet"
Foreground="White"
BorderThickness="0" />
<Button Command="{Binding FatalGlobalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Fatal}}"
Margin="5,0" />
<Button Command="{Binding ClearGlobalCmd}"
Content="{ex:Lang Key={x:Static langs:LangKeys.Clear}}"
Margin="5,0,0,0"
Style="{StaticResource ButtonPrimary}" />
</WrapPanel>
</GroupBox>
</StackPanel>
</hc:UniformSpacingPanel>
</hc:TransitioningContentControl>
</UserControl>
@@ -1,4 +1,5 @@
using System.Windows;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using HandyControl.Controls;
using HandyControl.Data;
@@ -6,10 +7,12 @@ using HandyControlDemo.Window;
namespace HandyControlDemo.ViewModel;
public class GrowlDemoViewModel
public class GrowlDemoViewModel : ViewModelBase
{
private readonly string _token;
private TransitionMode _transitionMode;
public GrowlDemoViewModel()
{
@@ -20,6 +23,24 @@ public class GrowlDemoViewModel
_token = token;
}
public TransitionMode TransitionMode
{
get => _transitionMode;
#if NET40
set
{
Set(nameof(TransitionMode), ref _transitionMode, value);
Growl.SetTransitionMode(Application.Current.MainWindow, value);
}
#else
set
{
Set(ref _transitionMode, value);
Growl.SetTransitionMode(Application.Current.MainWindow, value);
}
#endif
}
#region Window
public RelayCommand InfoCmd => new(() => Growl.Info(Properties.Langs.Lang.GrowlInfo, _token));
@@ -47,11 +47,13 @@ public class Growl : Control
"ShowMode", typeof(GrowlShowMode), typeof(Growl),
new FrameworkPropertyMetadata(default(GrowlShowMode), FrameworkPropertyMetadataOptions.Inherits));
public static readonly DependencyProperty TransitionModeProperty = DependencyProperty.Register(
nameof(TransitionMode), typeof(TransitionMode), typeof(Growl), new PropertyMetadata(default(TransitionMode)));
public static readonly DependencyProperty TransitionModeProperty = DependencyProperty.RegisterAttached(
"TransitionMode", typeof(TransitionMode), typeof(Growl),
new FrameworkPropertyMetadata(default(TransitionMode), FrameworkPropertyMetadataOptions.Inherits));
public static readonly DependencyProperty TransitionStoryboardProperty = DependencyProperty.Register(
nameof(TransitionStoryboard), typeof(Storyboard), typeof(Growl), new PropertyMetadata(default(Storyboard)));
public static readonly DependencyProperty TransitionStoryboardProperty = DependencyProperty.RegisterAttached(
"TransitionStoryboard", typeof(Storyboard), typeof(Growl),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
public static readonly DependencyProperty ShowDateTimeProperty = DependencyProperty.Register(
nameof(ShowDateTime), typeof(bool), typeof(Growl), new PropertyMetadata(ValueBoxes.TrueBox));
@@ -105,18 +107,6 @@ public class Growl : Control
/// </summary>
public static Panel GrowlPanel { get; set; }
public TransitionMode TransitionMode
{
get => (TransitionMode) GetValue(TransitionModeProperty);
set => SetValue(TransitionModeProperty, value);
}
public Storyboard TransitionStoryboard
{
get => (Storyboard) GetValue(TransitionStoryboardProperty);
set => SetValue(TransitionStoryboardProperty, value);
}
public InfoType Type
{
get => (InfoType) GetValue(TypeProperty);
@@ -231,6 +221,18 @@ public class Growl : Control
public static GrowlShowMode GetShowMode(DependencyObject element) =>
(GrowlShowMode) element.GetValue(ShowModeProperty);
public static void SetTransitionMode(DependencyObject element, TransitionMode value)
=> element.SetValue(TransitionModeProperty, value);
public static TransitionMode GetTransitionMode(DependencyObject element)
=> (TransitionMode) element.GetValue(TransitionModeProperty);
public static void SetTransitionStoryboard(DependencyObject element, Storyboard value)
=> element.SetValue(TransitionStoryboardProperty, value);
public static Storyboard GetTransitionStoryboard(DependencyObject element)
=> (Storyboard) element.GetValue(TransitionStoryboardProperty);
public static void SetGrowlParent(DependencyObject element, bool value) =>
element.SetValue(GrowlParentProperty, ValueBoxes.BooleanBox(value));
@@ -371,7 +373,6 @@ public class Growl : Control
CancelStr = growlInfo.CancelStr,
Type = growlInfo.Type,
_waitTime = Math.Max(growlInfo.WaitTime, MinWaitTime),
FlowDirection = growlInfo.FlowDirection
};
ShowInternal(GrowlWindow.GrowlPanel, ctl);
@@ -422,6 +423,10 @@ public class Growl : Control
// GrowlPanel is null, we create it automatically
GrowlPanel ??= CreateDefaultPanel();
ShowInternal(GrowlPanel, ctl);
var transitionMode = GetTransitionMode(ctl);
GrowlPanel.VerticalAlignment = GetPanelVerticalAlignment(transitionMode);
GrowlPanel.HorizontalAlignment = GetPanelHorizontalAlignment(transitionMode);
}
}
#if NET40
@@ -435,40 +440,33 @@ public class Growl : Control
FrameworkElement element = WindowHelper.GetActiveWindow();
var decorator = VisualHelper.GetChild<AdornerDecorator>(element);
if (decorator != null)
var layer = decorator?.AdornerLayer;
if (layer == null)
{
var layer = decorator.AdornerLayer;
if (layer != null)
{
var panel = new StackPanel
{
VerticalAlignment = VerticalAlignment.Top
};
InitGrowlPanel(panel);
SetIsCreatedAutomatically(panel, true);
var scrollViewer = new ScrollViewer
{
HorizontalAlignment = HorizontalAlignment.Right,
VerticalScrollBarVisibility = ScrollBarVisibility.Hidden,
IsInertiaEnabled = true,
IsPenetrating = true,
Content = panel
};
var container = new AdornerContainer(layer)
{
Child = scrollViewer
};
layer.Add(container);
return panel;
}
return null;
}
return null;
var panel = new SimpleStackPanel();
InitGrowlPanel(panel);
SetIsCreatedAutomatically(panel, true);
var scrollViewer = new ScrollViewer
{
VerticalScrollBarVisibility = ScrollBarVisibility.Hidden,
IsInertiaEnabled = true,
IsPenetrating = true,
Content = panel
};
var container = new AdornerContainer(layer)
{
Child = scrollViewer
};
layer.Add(container);
return panel;
}
private static void RemoveDefaultPanel(Panel panel)
@@ -918,7 +916,7 @@ public class Growl : Control
private void StartTransition(bool isClose, Action completed = null)
{
var actualStoryboard = TransitionStoryboard ?? CreateStoryboard(isClose, TransitionMode);
var actualStoryboard = GetTransitionStoryboard(this) ?? CreateStoryboard(isClose, GetTransitionMode(this));
if (actualStoryboard is null)
{
return;
@@ -1064,4 +1062,28 @@ public class Growl : Control
_ => null
};
}
private static VerticalAlignment GetPanelVerticalAlignment(TransitionMode transitionMode)
{
return transitionMode switch
{
TransitionMode.Right2Left or TransitionMode.Right2LeftWithFade or TransitionMode.Left2Right
or TransitionMode.Left2RightWithFade => VerticalAlignment.Top,
TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade => VerticalAlignment.Bottom,
TransitionMode.Top2Bottom or TransitionMode.Top2BottomWithFade => VerticalAlignment.Top,
_ => VerticalAlignment.Stretch
};
}
private static HorizontalAlignment GetPanelHorizontalAlignment(TransitionMode transitionMode)
{
return transitionMode switch
{
TransitionMode.Right2Left or TransitionMode.Right2LeftWithFade => HorizontalAlignment.Right,
TransitionMode.Left2Right or TransitionMode.Left2RightWithFade => HorizontalAlignment.Left,
TransitionMode.Bottom2Top or TransitionMode.Bottom2TopWithFade or TransitionMode.Top2Bottom
or TransitionMode.Top2BottomWithFade => HorizontalAlignment.Center,
_ => HorizontalAlignment.Stretch
};
}
}
@@ -37,6 +37,7 @@ public class GrowlInfo
public string Token { get; set; }
[Obsolete("use TransitionMode instead")]
public FlowDirection FlowDirection { get; set; }
public Dispatcher Dispatcher { get; set; }