瀏覽代碼

polish notifications

Dan Walmsley 6 年之前
父節點
當前提交
f8f5610b8c

+ 4 - 15
samples/ControlCatalog/ViewModels/MainWindowViewModel.cs

@@ -1,12 +1,7 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
 using System.Threading.Tasks;
-using Avalonia;
 using Avalonia.Controls.Notifications;
 using Avalonia.Diagnostics.ViewModels;
 using Avalonia.Threading;
-using ReactiveUI;
 
 namespace ControlCatalog.ViewModels
 {
@@ -14,26 +9,20 @@ namespace ControlCatalog.ViewModels
     {
         public MainWindowViewModel()
         {
-            this.WhenAnyValue(x => x.NotificationManager).Subscribe(x =>
-            {
-
-            });
-
             Dispatcher.UIThread.InvokeAsync(async () =>
             {
                 await Task.Delay(5000);
 
-
-                NotificationManager.Show(new NotificationViewModel { Title = "Warning", Message = "Please save your work before closing." });
+                NotificationManager.Show(new NotificationViewModel (NotificationManager) { Title = "Warning", Message = "Did you know that Avalonia now supports Notifications?" });
 
                 await Task.Delay(1500);
-                NotificationManager.Show(new NotificationContent { Message = "Test2", Type = NotificationType.Error });
+                NotificationManager.Show(new NotificationContent { Title= "Title", Message = "Test2", Type = NotificationType.Error });
 
                 await Task.Delay(2000);
-                NotificationManager.Show(new NotificationContent { Message = "Test3", Type = NotificationType.Warning });
+                NotificationManager.Show(new NotificationContent { Title = "Title", Message = "Test3", Type = NotificationType.Warning });
 
                 await Task.Delay(2500);
-                NotificationManager.Show(new NotificationContent { Message = "Test4", Type = NotificationType.Success });
+                NotificationManager.Show(new NotificationContent { Title = "Title", Message = "Test4", Type = NotificationType.Success });
 
                 await Task.Delay(500);
                 NotificationManager.Show("Test5");

+ 11 - 4
samples/ControlCatalog/ViewModels/NotificationViewModel.cs

@@ -7,18 +7,25 @@ namespace ControlCatalog.ViewModels
 {
     public class NotificationViewModel
     {
-        public NotificationViewModel()
+        public NotificationViewModel(INotificationManager manager)
         {
-            OKCommand = ReactiveCommand.Create(() =>
+            YesCommand = ReactiveCommand.Create(() =>
             {
-                Application.Current.MainWindow.LocalNotificationManager.Show("Notification Accepted");
+                manager.Show(new NotificationContent { Title = "Avalonia Notifications", Message = "Start adding notifications to your app today." });
+            });
+
+            NoCommand = ReactiveCommand.Create(() =>
+            {
+                manager.Show(new NotificationContent { Title = "Avalonia Notifications", Message = "Start adding notifications to your app today. To find out more visit..." });
             });
         }
 
         public string Title { get; set; }
         public string Message { get; set; }
 
-        public ReactiveCommand<Unit, Unit> OKCommand { get; }
+        public ReactiveCommand<Unit, Unit> YesCommand { get; }
+
+        public ReactiveCommand<Unit, Unit> NoCommand { get; }
 
     }
 }

+ 4 - 4
samples/ControlCatalog/Views/NotificationView.xaml

@@ -8,10 +8,10 @@
             </Panel>
             <DockPanel Grid.Column="1">
                 <TextBlock DockPanel.Dock="Top" Text="{Binding Title}" FontWeight="Medium" />
-                <DockPanel LastChildFill="False" DockPanel.Dock="Bottom" Margin="0,8,0,0">
-                    <Button Content="Ok" DockPanel.Dock="Right" Notification.CloseOnClick="True" Command="{Binding OKCommand}" />
-                    <Button Content="Cancel" DockPanel.Dock="Right" Notification.CloseOnClick="True" Margin="0,0,8,0" />
-                </DockPanel>
+                <StackPanel Spacing="20" DockPanel.Dock="Bottom" Margin="0,8,0,0">
+                    <Button Content="No" DockPanel.Dock="Right" Notification.CloseOnClick="True" Command="{Binding NoCommand}"  Margin="0,0,8,0" />
+                    <Button Content="Yes" DockPanel.Dock="Right" Notification.CloseOnClick="True" Command="{Binding YesCommand}" />
+                </StackPanel>
                 <TextBlock Text="{Binding Message}" TextWrapping="Wrap" Opacity=".8" Margin="0,8,0,0"/>
             </DockPanel>
         </Grid>

+ 2 - 0
src/Avalonia.Controls/Notifications/INotificationManager.cs

@@ -5,5 +5,7 @@ namespace Avalonia.Controls.Notifications
     public interface INotificationManager
     {
         void Show(object content, TimeSpan? expirationTime = null, Action onClick = null, Action onClose = null);
+
+        void Show(NotificationContent content, TimeSpan? expirationTime = null, Action onClick = null, Action onClose = null);
     }
 }

+ 6 - 4
src/Avalonia.Controls/Notifications/Notification.cs

@@ -9,6 +9,9 @@ namespace Avalonia.Controls.Notifications
 {
     public class Notification : ContentControl
     {
+        private bool _isClosed;
+        private bool _isClosing;
+
         static Notification()
         {
             IsClosedProperty.Changed.AddClassHandler<Notification>(IsClosedChanged);
@@ -41,8 +44,6 @@ namespace Avalonia.Controls.Notifications
                 });
         }
 
-        private bool _isClosing;
-
         /// <summary>
         /// Determines if the notification is already closing.
         /// </summary>
@@ -55,8 +56,6 @@ namespace Avalonia.Controls.Notifications
         public static readonly DirectProperty<Notification, bool> IsClosingProperty =
             AvaloniaProperty.RegisterDirect<Notification, bool>(nameof(IsClosing), o => o.IsClosing);
 
-        private bool _isClosed;
-
         /// <summary>
         /// Determines if the notification is closed.
         /// </summary>
@@ -66,6 +65,9 @@ namespace Avalonia.Controls.Notifications
             set { SetAndRaise(IsClosedProperty, ref _isClosed, value); }
         }
 
+        /// <summary>
+        /// Defines the <see cref="IsClosed"/> property.
+        /// </summary>
         public static readonly DirectProperty<Notification, bool> IsClosedProperty =
             AvaloniaProperty.RegisterDirect<Notification, bool>(nameof(IsClosed), o => o.IsClosed, (o, v) => o.IsClosed = v);
 

+ 5 - 4
src/Avalonia.Controls/Notifications/NotificationArea.cs

@@ -29,10 +29,6 @@ namespace Avalonia.Controls.Notifications
         public static readonly AvaloniaProperty MaxItemsProperty =
             AvaloniaProperty.Register<NotificationArea, int>(nameof(MaxItems), int.MaxValue);
 
-        public NotificationArea()
-        {
-        }
-
         static NotificationArea()
         {
             PseudoClass<NotificationArea, NotificationPosition>(PositionProperty, x => x == NotificationPosition.TopLeft, ":topleft");
@@ -52,6 +48,11 @@ namespace Avalonia.Controls.Notifications
             _items = itemsControl?.Children;
         }
 
+        public void Show(NotificationContent content, TimeSpan? expirationTime, Action onClick, Action onClose)
+        {
+             Show(content as object, expirationTime, onClick, onClose);
+        }
+
         public async void Show(object content, TimeSpan? expirationTime, Action onClick, Action onClose)
         {
             var notification = new Notification

+ 6 - 0
src/Avalonia.Controls/Notifications/NotificationContent.cs

@@ -4,6 +4,12 @@ using System.Text;
 
 namespace Avalonia.Controls.Notifications
 {
+    /// <summary>
+    /// Defines content for a <see cref="Notification"/> control.
+    /// </summary>
+    /// <remarks>
+    /// This notification content type is compatible with native notifications.
+    /// </remarks>
     public class NotificationContent
     {
         public string Title { get; set; }

+ 4 - 4
src/Avalonia.Controls/TopLevel.cs

@@ -51,8 +51,8 @@ namespace Avalonia.Controls
         /// <summary>
         /// Defines the <see cref="LocalNotificationManager"/> property.
         /// </summary>
-        public static readonly DirectProperty<TopLevel, INotificationManager> LocalNotificationManagerProperty =
-            AvaloniaProperty.RegisterDirect<TopLevel, INotificationManager>(nameof(LocalNotificationManager), o => o.LocalNotificationManager, (o, v) => o.LocalNotificationManager = v);
+        public static readonly DirectProperty<TopLevel, NotificationArea> LocalNotificationManagerProperty =
+            AvaloniaProperty.RegisterDirect<TopLevel, NotificationArea>(nameof(LocalNotificationManager), o => o.LocalNotificationManager, (o, v) => o.LocalNotificationManager = v);
 
         /// <summary>
         /// Defines the <see cref="SystemNotificationManager"/> property.
@@ -66,7 +66,7 @@ namespace Avalonia.Controls
         private readonly IApplicationLifecycle _applicationLifecycle;
         private readonly IPlatformRenderInterface _renderInterface;
         private Size _clientSize;
-        private INotificationManager _localNotificationManager;
+        private NotificationArea _localNotificationManager;
         private INotificationManager _systemNotificationManager;
         private ILayoutManager _layoutManager;
 
@@ -184,7 +184,7 @@ namespace Avalonia.Controls
         /// <summary>
         /// Gets or sets the Local (in window managed) notification manager.
         /// </summary>
-        public INotificationManager LocalNotificationManager
+        public NotificationArea LocalNotificationManager
         {
             get => _localNotificationManager;
             protected set => SetAndRaise(LocalNotificationManagerProperty, ref _localNotificationManager, value);

+ 22 - 29
src/Avalonia.Themes.Default/NotificationArea.xaml

@@ -6,17 +6,10 @@
                 <StackPanel Name="PART_Items">
                     <StackPanel.DataTemplates>
                         <DataTemplate DataType="NotificationContent">
-                            <Border Padding="12" MinHeight="80">
-                                <Grid ColumnDefinitions="Auto,*">
-                                    <ContentControl Margin="0,0,12,0" Width="25" Height="25" VerticalAlignment="Top">
-                                        <ContentControl HorizontalAlignment="Center" VerticalAlignment="Center"/>
-                                    </ContentControl>
-                                    <DockPanel Grid.Column="1">
-                                        <TextBlock DockPanel.Dock="Top" Text="{Binding Title}" FontWeight="Medium" />
-                                        <TextBlock Text="{Binding Message}" TextWrapping="Wrap" Opacity=".8" Margin="0,0,12,0"/>
-                                    </DockPanel>
-                                </Grid>
-                            </Border>
+                            <StackPanel Spacing="8">
+                                <TextBlock DockPanel.Dock="Top" Text="{Binding Title}" FontWeight="Medium" />
+                                <TextBlock MaxHeight="80" Text="{Binding Message}" TextWrapping="Wrap" Opacity=".8" Margin="0,0,12,0"/>
+                            </StackPanel>
                         </DataTemplate>
                     </StackPanel.DataTemplates>
                 </StackPanel>
@@ -33,7 +26,11 @@
         <Setter Property="Template">
             <ControlTemplate>
                 <LayoutTransformControl Name="PART_LayoutTransformControl" UseRenderTransform="True">
-                    <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Margin="8,8,0,0">
+                    <Border Background="{TemplateBinding Background}" 
+                            BorderBrush="{TemplateBinding BorderBrush}" 
+                            BorderThickness="{TemplateBinding BorderThickness}"
+                            Margin="8,8,0,0"
+                            Padding="12">
                         <ContentControl MinHeight="150" Content="{TemplateBinding Content}" />
                     </Border>
                 </LayoutTransformControl>
@@ -41,15 +38,15 @@
         </Setter>
 
         <Style.Animations>
-            <Animation Duration="0:0:0.35" Easing="QuadraticEaseIn" FillMode="Forward">
+            <Animation Duration="0:0:0.45" Easing="QuadraticEaseIn" FillMode="Forward">
                 <KeyFrame Cue="0%">
                     <Setter Property="Opacity" Value="0"/>
-                    <Setter Property="TranslateTransform.Y" Value="-20"/>
+                    <Setter Property="TranslateTransform.Y" Value="20"/>
                     <Setter Property="ScaleTransform.ScaleX" Value="0.85"/>
                     <Setter Property="ScaleTransform.ScaleY" Value="0.85"/>
                 </KeyFrame>
                 <KeyFrame Cue="30%">
-                    <Setter Property="TranslateTransform.Y" Value="20"/>
+                    <Setter Property="TranslateTransform.Y" Value="-20"/>
                 </KeyFrame>
                 <KeyFrame Cue="100%">
                     <Setter Property="Opacity" Value="1"/>
@@ -64,14 +61,18 @@
     <Style Selector="Notification[IsClosing=true] /template/ LayoutTransformControl#PART_LayoutTransformControl">
         <Setter Property="RenderTransformOrigin" Value="50%,0%"/>
         <Style.Animations>
-            <Animation Duration="0:0:0.25" Easing="QuadraticEaseOut" FillMode="Forward">
+            <Animation Duration="0:0:0.75" Easing="QuadraticEaseOut" FillMode="Forward">
                 <KeyFrame Cue="0%">
-                    <Setter Property="Opacity" Value="1"/>
+                    <Setter Property="TranslateTransform.X" Value="0"/>
+                    <Setter Property="ScaleTransform.ScaleY" Value="1"/>
+                </KeyFrame>
+                <KeyFrame Cue="70%">
+                    <Setter Property="TranslateTransform.X" Value="800"/>
                     <Setter Property="ScaleTransform.ScaleY" Value="1"/>
                 </KeyFrame>
                 <KeyFrame Cue="100%">
-                    <Setter Property="Opacity" Value="0"/>
                     <Setter Property="ScaleTransform.ScaleY" Value="0"/>
+                    <Setter Property="TranslateTransform.X" Value="800"/>
                 </KeyFrame>
             </Animation>
         </Style.Animations>
@@ -79,7 +80,7 @@
 
     <Style Selector="Notification[IsClosing=true]">
         <Style.Animations>
-            <Animation Duration="0:0:0.25" Easing="QuadraticEaseOut" FillMode="Forward">
+            <Animation Duration="0:0:1.25" Easing="QuadraticEaseOut" FillMode="Forward">
                 <KeyFrame Cue="100%">
                     <Setter Property="IsClosed" Value="True"/>
                 </KeyFrame>
@@ -98,25 +99,17 @@
         <Setter Property="HorizontalAlignment" Value="Right"/>
         <Setter Property="VerticalAlignment" Value="Top"/>
     </Style>
-
-    <Style Selector="Notification">
-        <!--<Setter TargetName="Icon" Property="Content" Value="{StaticResource InfoIcon}"/>-->
-        <Setter Property="Background" Value="#444444"/>
-    </Style>
+    
     <Style Selector="Notification:information">
-        <!--<Setter TargetName="Icon" Property="Content" Value="{StaticResource InfoIcon}"/>-->
-        <Setter Property="Background" Value="CornflowerBlue"/>
+        <Setter Property="Background" Value="Teal"/>
     </Style>
     <Style Selector="Notification:success">
-        <!--<Setter TargetName="Icon" Property="Content" Value="{StaticResource InfoIcon}"/>-->
         <Setter Property="Background" Value="LimeGreen"/>
     </Style>
     <Style Selector="Notification:warning">
-        <!--<Setter TargetName="Icon" Property="Content" Value="{StaticResource InfoIcon}"/>-->
         <Setter Property="Background" Value="Orange"/>
     </Style>
     <Style Selector="Notification:error">
-        <!--<Setter TargetName="Icon" Property="Content" Value="{StaticResource InfoIcon}"/>-->
         <Setter Property="Background" Value="OrangeRed"/>
     </Style>