├── .gitignore
├── License.md
├── LightSwitch_64x.png
├── README.md
├── appveyor.yml
└── source
├── CleanAll.bat
├── UserNotification.sln
├── UserNotification
├── Events
│ └── ShowNotificationEvent.cs
├── Interfaces
│ └── INotifyableViewModel.cs
├── Local
│ ├── Strings.Designer.cs
│ ├── Strings.de-DE.Designer.cs
│ ├── Strings.de-DE.resx
│ ├── Strings.es-ES.Designer.cs
│ ├── Strings.es-ES.resx
│ ├── Strings.fr-FR.Designer.cs
│ ├── Strings.fr-FR.resx
│ ├── Strings.hi.Designer.cs
│ ├── Strings.hi.resx
│ ├── Strings.it-IT.Designer.cs
│ ├── Strings.it-IT.resx
│ ├── Strings.nl-NL.Designer.cs
│ ├── Strings.nl-NL.resx
│ ├── Strings.resx
│ ├── Strings.zh-Hans.Designer.cs
│ └── Strings.zh-Hans.resx
├── Properties
│ └── AssemblyInfo.cs
├── Resources
│ ├── CloseButtonStyle.xaml
│ ├── close.png
│ ├── close_x.svg
│ ├── close_x_dark.png
│ └── close_x_light.png
├── Themes
│ ├── DarkBrushs.xaml
│ ├── Generic.xaml
│ ├── LightBrushs.xaml
│ └── ResourceKeys.cs
├── UserNotification.csproj
├── View
│ ├── NotificationCloseButton.cs
│ ├── NotificationWindow.xaml
│ ├── NotificationWindow.xaml.cs
│ ├── NotifyableContentControl.cs
│ ├── NotifyableWindow.cs
│ ├── SimpleNotificationWindow.xaml
│ └── SimpleNotificationWindow.xaml.cs
└── ViewModel
│ ├── Base
│ └── ViewModelBase.cs
│ ├── NotificationViewModel.cs
│ └── SendNotificationViewModel.cs
└── UserNotificationDemo
├── App.xaml
├── App.xaml.cs
├── Command
└── RelayCommand.cs
├── Resources
├── Radiation_warning_symbol.png
├── facebook-button.png
├── microsoft-windows-8-logo.png
└── notification-icon.png
├── UserNotificationDemo.csproj
├── UserNotificationDemo.csproj.user
├── ViewModels
├── Base
│ └── ViewModelBase.cs
├── TestNotifyableContentControlViewModel.cs
└── TestViewModel.cs
├── Views
├── BindingProxy.cs
├── MainWindow.xaml
└── MainWindow.xaml.cs
└── app.config
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Visual Studio 2015 cache/options directory
3 | .vs/
4 |
5 | 00_Release/
6 | 01_Nuget/
7 | debug/
8 | release/
9 | build/
10 | bin/
11 | obj/
12 | cache/
13 | log/
14 | tmp/
15 |
16 | *~
17 | *.lock
18 | *.DS_Store
19 | *.swp
20 | *.out
21 | *.sou
22 | *.suo
23 | *.sqlite
24 | /source/.vs/UserNotification/v15/sqlite3/storage.ide
25 |
--------------------------------------------------------------------------------
/License.md:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2014-2017 Dirk Bahle
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/LightSwitch_64x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/LightSwitch_64x.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://ci.appveyor.com/project/Dirkster99/usernotifications)
2 | [](https://github.com/Dirkster99/UserNotifications/releases/latest)
3 | [](http://nuget.org/packages/Dirkster.UserNotifications)
4 |
5 |  
6 |
7 | ## Overview
8 |
9 | Lightweight notifications for WPF project based on
10 |
11 | 
12 | 
13 |
14 | Lightweight growl notifications for WPF project from here:
15 | http://www.codeproject.com/Articles/499241/Growl-Alike-WPF-Notifications
16 |
17 | ## Theming
18 |
19 | Load *Light* or *Dark* brush resources in you resource dictionary to take advantage of existing definitions.
20 |
21 | ```XAML
22 |
23 |
24 |
25 | ```
26 |
27 | ```XAML
28 |
29 |
30 |
31 | ```
32 |
33 | These definitions do not theme all controls used within this library. You should use a standard theming library, such as:
34 | - [MahApps.Metro](https://github.com/MahApps/MahApps.Metro),
35 | - [MLib](https://github.com/Dirkster99/MLib), or
36 | - [MUI](https://github.com/firstfloorsoftware/mui)
37 |
38 | to also theme standard elements, such as, button and textblock etc.
39 |
40 | ## Requirements
41 |
42 | - Visual Studio 2012 / 2010 or later
43 |
44 | ## Sample Screenshots
45 | 
46 | 
47 | 
48 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: 1.5.{build}
2 |
3 | branches:
4 | only:
5 | - master
6 |
7 | #dotnet_csproj:
8 | # patch: true
9 | # file: '**\*.csproj'
10 | # version: '{version}'
11 | # package_version: '{version}'
12 | # assembly_version: '{version}'
13 | # file_version: '{version}'
14 | # informational_version: '{version}'
15 |
16 | before_build:
17 | - cmd: nuget restore source/UserNotification.sln
18 |
19 | build:
20 | verbosity: minimal
21 |
22 | configuration: Release
23 |
24 | platform: Any CPU
25 |
26 | image: Visual Studio 2019 Preview
27 |
28 | install:
29 | - cmd: choco install dotnetcore-sdk --pre
30 |
31 | artifacts:
32 | - path: source\UserNotification\bin\Release
33 |
--------------------------------------------------------------------------------
/source/CleanAll.bat:
--------------------------------------------------------------------------------
1 | @ECHO OFF
2 | pushd "%~dp0"
3 | ECHO.
4 | ECHO.
5 | ECHO This script deletes all temporary build files in their
6 | ECHO corresponding BIN and OBJ Folder contained in the following projects
7 | ECHO.
8 | ECHO UserNotification
9 | ECHO UserNotificationDemo
10 | ECHO.
11 | REM Ask the user if hes really sure to continue beyond this point XXXXXXXX
12 | set /p choice=Are you sure to continue (Y/N)?
13 | if not '%choice%'=='Y' Goto EndOfBatch
14 | REM Script does not continue unless user types 'Y' in upper case letter
15 | ECHO.
16 | ECHO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
17 | ECHO.
18 | ECHO XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
19 |
20 | ECHO.
21 | ECHO Deleting .vs and BIN, OBJ Folders in project folder
22 | ECHO.
23 | RMDIR .vs /S /Q
24 |
25 | RMDIR /S /Q UserNotification\bin
26 | RMDIR /S /Q UserNotification\obj
27 |
28 | RMDIR /S /Q UserNotificationDemo\bin
29 | RMDIR /S /Q UserNotificationDemo\obj
30 |
31 | PAUSE
32 |
33 | :EndOfBatch
34 |
--------------------------------------------------------------------------------
/source/UserNotification.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio Version 16
4 | VisualStudioVersion = 16.0.28407.52
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UserNotification", "UserNotification\UserNotification.csproj", "{AF255663-9320-4EBA-92CF-D0D6AAC951C0}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UserNotificationDemo", "UserNotificationDemo\UserNotificationDemo.csproj", "{6995ABFD-720F-41E7-BE8B-38F23BA4BB57}"
9 | EndProject
10 | Global
11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
12 | Debug|Any CPU = Debug|Any CPU
13 | Debug|x86 = Debug|x86
14 | Release|Any CPU = Release|Any CPU
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Debug|x86.ActiveCfg = Debug|Any CPU
21 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Debug|x86.Build.0 = Debug|Any CPU
22 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Release|Any CPU.ActiveCfg = Release|Any CPU
23 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Release|Any CPU.Build.0 = Release|Any CPU
24 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Release|x86.ActiveCfg = Release|Any CPU
25 | {AF255663-9320-4EBA-92CF-D0D6AAC951C0}.Release|x86.Build.0 = Release|Any CPU
26 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Debug|x86.ActiveCfg = Debug|Any CPU
29 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Debug|x86.Build.0 = Debug|Any CPU
30 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Release|Any CPU.ActiveCfg = Release|Any CPU
31 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Release|Any CPU.Build.0 = Release|Any CPU
32 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Release|x86.ActiveCfg = Release|Any CPU
33 | {6995ABFD-720F-41E7-BE8B-38F23BA4BB57}.Release|x86.Build.0 = Release|Any CPU
34 | EndGlobalSection
35 | GlobalSection(SolutionProperties) = preSolution
36 | HideSolutionNode = FALSE
37 | EndGlobalSection
38 | GlobalSection(ExtensibilityGlobals) = postSolution
39 | SolutionGuid = {8ECC8A60-05D9-4318-AE29-80ACF81DF548}
40 | EndGlobalSection
41 | EndGlobal
42 |
--------------------------------------------------------------------------------
/source/UserNotification/Events/ShowNotificationEvent.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.Events
2 | {
3 | using System;
4 | using System.Windows;
5 | using System.Windows.Controls.Primitives;
6 | using System.Windows.Media.Imaging;
7 |
8 | ///
9 | /// Event handler delegation method to be used when handling events.
10 | ///
11 | ///
12 | ///
13 | public delegate void ShowNotificationEventHandler(object sender, ShowNotificationEvent e);
14 |
15 | ///
16 | /// This class is used to message the fact that the sub-system would like to show another notification
17 | /// to the user.
18 | ///
19 | /// Expectation: The connected view is processing the event and shows a (pop-up) message to the user.
20 | ///
21 | public class ShowNotificationEvent : EventArgs
22 | {
23 | #region constructor
24 | ///
25 | /// Initializes a new instance of the ShowNotificationEvent class.
26 | ///
27 | ///
28 | ///
29 | ///
30 | public ShowNotificationEvent(string title,
31 | string message,
32 | BitmapImage imageIcon)
33 | {
34 | this.Title = title;
35 | this.Message = message;
36 | this.ImageIcon = imageIcon;
37 | }
38 | #endregion constructor
39 |
40 | #region properties
41 | ///
42 | /// Get the title string of notification.
43 | ///
44 | public string Title { get; protected set; }
45 |
46 | ///
47 | /// Get message of notification.
48 | ///
49 | public string Message { get; protected set; }
50 |
51 | ///
52 | /// Get url string to an image resource that represents this type of notification.
53 | ///
54 | public BitmapImage ImageIcon { get; protected set; }
55 | #endregion properties
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/source/UserNotification/Interfaces/INotifyableViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.Interfaces
2 | {
3 | ///
4 | /// This interface can be used to connect viewmodel with view
5 | /// when showing notifications that can pop-up over a window
6 | /// or over all currently visible windows (IsTopMost = true in notification viewmodel)
7 | ///
8 | public interface INotifyableViewModel
9 | {
10 | ///
11 | /// Expose an event that is triggered when the viewmodel tells its view:
12 | /// Here is another notification message please show it to the user.
13 | ///
14 | event UserNotification.Events.ShowNotificationEventHandler ShowNotificationMessage;
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace UserNotification.Local {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | public class Strings {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Strings() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | public static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("UserNotification.Local.Strings", typeof(Strings).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | public static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 |
63 | ///
64 | /// Looks up a localized string similar to Close.
65 | ///
66 | public static string Close_Tip_Label {
67 | get {
68 | return ResourceManager.GetString("Close_Tip_Label", resourceCulture);
69 | }
70 | }
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.de-DE.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Local/Strings.de-DE.Designer.cs
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.de-DE.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Schließen
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.es-ES.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Local/Strings.es-ES.Designer.cs
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.es-ES.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Cerrar
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.fr-FR.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Local/Strings.fr-FR.Designer.cs
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.fr-FR.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Fermer
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.hi.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Local/Strings.hi.Designer.cs
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.hi.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | बंद करें
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.it-IT.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Local/Strings.it-IT.Designer.cs
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.it-IT.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Chiudi
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.nl-NL.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Local/Strings.nl-NL.Designer.cs
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.nl-NL.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Sluiten
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | Close
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.zh-Hans.Designer.cs:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Local/Strings.zh-Hans.Designer.cs
--------------------------------------------------------------------------------
/source/UserNotification/Local/Strings.zh-Hans.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 | text/microsoft-resx
110 |
111 |
112 | 2.0
113 |
114 |
115 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
118 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
119 |
120 |
121 | 关闭
122 | Close
123 |
124 |
--------------------------------------------------------------------------------
/source/UserNotification/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Runtime.InteropServices;
2 | using System.Windows;
3 |
4 | // Setting ComVisible to false makes the types in this assembly not visible
5 | // to COM components. If you need to access a type in this assembly from
6 | // COM, set the ComVisible attribute to true on that type.
7 | [assembly: ComVisible(false)]
8 |
9 |
10 |
11 | [assembly: ThemeInfo(
12 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
13 | //(used if a resource is not found in the page,
14 | // or application resource dictionaries)
15 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
16 | //(used if a resource is not found in the page,
17 | // app, or any theme specific resource dictionaries)
18 | )]
19 |
--------------------------------------------------------------------------------
/source/UserNotification/Resources/CloseButtonStyle.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
59 |
--------------------------------------------------------------------------------
/source/UserNotification/Resources/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Resources/close.png
--------------------------------------------------------------------------------
/source/UserNotification/Resources/close_x.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/source/UserNotification/Resources/close_x_dark.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Resources/close_x_dark.png
--------------------------------------------------------------------------------
/source/UserNotification/Resources/close_x_light.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotification/Resources/close_x_light.png
--------------------------------------------------------------------------------
/source/UserNotification/Themes/DarkBrushs.xaml:
--------------------------------------------------------------------------------
1 |
6 |
8 | #FF2C628B
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/source/UserNotification/Themes/Generic.xaml:
--------------------------------------------------------------------------------
1 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/source/UserNotification/Themes/LightBrushs.xaml:
--------------------------------------------------------------------------------
1 |
6 |
8 | #FF2C628B
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
35 |
36 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/source/UserNotification/Themes/ResourceKeys.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.Themes
2 | {
3 | using System.Windows;
4 |
5 | ///
6 | /// Resource key management class to keep track of all resources
7 | /// that can be re-styled in applications that make use of the implemented controls.
8 | ///
9 | public static class ResourceKeys
10 | {
11 | #region Accent Keys
12 | ///
13 | /// Accent Color Key - This Color key is used to accent elements in the UI
14 | /// (e.g.: Color of Activated Normal Window Frame, ResizeGrip, Focus or MouseOver input elements)
15 | ///
16 | public static readonly ComponentResourceKey ControlAccentColorKey = new ComponentResourceKey(typeof(ResourceKeys), "ControlAccentColorKey");
17 |
18 | ///
19 | /// Accent Brush Key - This Brush key is used to accent elements in the UI
20 | /// (e.g.: Color of Activated Normal Window Frame, ResizeGrip, Focus or MouseOver input elements)
21 | ///
22 | public static readonly ComponentResourceKey ControlAccentBrushKey = new ComponentResourceKey(typeof(ResourceKeys), "ControlAccentBrushKey");
23 | #endregion Accent Keys
24 |
25 | #region Brush Keys
26 | ///
27 | /// Resource key of the controls normal background brush key.
28 | ///
29 | public static readonly ComponentResourceKey ControlNormalBackgroundKey = new ComponentResourceKey(typeof(ResourceKeys), "ControlNormalBackgroundKey");
30 | #endregion Brush Keys
31 |
32 | ///
33 | /// Background brush key of the NotificationWindow.
34 | ///
35 | public static readonly ComponentResourceKey NotificationWindowBackground = new ComponentResourceKey(typeof(ResourceKeys), "NotificationWindowBackground");
36 |
37 | ///
38 | /// Border brush key of the border of the NotificationWindow.
39 | ///
40 | public static readonly ComponentResourceKey NotificationWindowBorder = new ComponentResourceKey(typeof(ResourceKeys), "NotificationWindowBorder");
41 |
42 | ///
43 | /// Foreground brush key the border of the NotificationWindow.
44 | ///
45 | public static readonly ComponentResourceKey NotificationWindowForeground = new ComponentResourceKey(typeof(ResourceKeys), "NotificationWindowForeground");
46 |
47 | // Close Button Brushes
48 |
49 | ///
50 | /// Border brush key of the focused border (of the close button)
51 | ///
52 | public static readonly ComponentResourceKey DefaultedBorderBrush = new ComponentResourceKey(typeof(ResourceKeys), "DefaultedBorderBrush");
53 |
54 | ///
55 | /// Border brush key of the disabled border (of the close button)
56 | ///
57 | public static readonly ComponentResourceKey DisabledForegroundBrush = new ComponentResourceKey(typeof(ResourceKeys), "DisabledForegroundBrush");
58 |
59 | ///
60 | /// Background brush key of the disabled control (of the close button)
61 | ///
62 | public static readonly ComponentResourceKey DisabledBackgroundBrush = new ComponentResourceKey(typeof(ResourceKeys), "DisabledBackgroundBrush");
63 |
64 | ///
65 | /// Broder brush key of the disabled control (of the close button)
66 | ///
67 | public static readonly ComponentResourceKey DisabledBorderBrush = new ComponentResourceKey(typeof(ResourceKeys), "DisabledBorderBrush");
68 |
69 | ///
70 | /// Border brush key of the border (of the close button)
71 | ///
72 | public static readonly ComponentResourceKey NormalBorderBrush = new ComponentResourceKey(typeof(ResourceKeys), "NormalBorderBrush");
73 |
74 | ///
75 | /// Normal background brush key (of the close button)
76 | ///
77 | public static readonly ComponentResourceKey CloseNormal = new ComponentResourceKey(typeof(ResourceKeys), "CloseNormal");
78 |
79 | ///
80 | /// Mouse over border brush key (of the close button)
81 | ///
82 | public static readonly ComponentResourceKey CloseOver = new ComponentResourceKey(typeof(ResourceKeys), "CloseOver");
83 |
84 | ///
85 | /// Button pressed background brush key (of the close button)
86 | ///
87 | public static readonly ComponentResourceKey ClosePressed = new ComponentResourceKey(typeof(ResourceKeys), "ClosePressed");
88 |
89 | ///
90 | /// Image resource key of the close button.
91 | ///
92 | public static readonly ComponentResourceKey Image_Close_Button = new ComponentResourceKey(typeof(ResourceKeys), "Image_Close_Button");
93 | }
94 | }
95 |
--------------------------------------------------------------------------------
/source/UserNotification/UserNotification.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Library
5 | net40;netcoreapp3.0
6 | true
7 |
8 |
9 |
10 | UserNotification
11 | Dirkster.UserNotifications
12 | UserNotification
13 | 2012 - 2018
14 | Open Source
15 | Themable user notifications WPF control through pop-up elements
16 | 1.5.1
17 | https://github.com/Dirkster99/UserNotification
18 | https://github.com/Dirkster99/UserNotification
19 | true
20 | https://raw.githubusercontent.com/Dirkster99/UserNotifications/master/LightSwitch_64x.png
21 | MIT
22 | Package Update with support based on .NetCore 3 Preview 8 and .Net4.5.
23 | en
24 |
25 |
26 |
27 |
41 |
42 |
--------------------------------------------------------------------------------
/source/UserNotification/View/NotificationCloseButton.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.View
2 | {
3 | using System.Windows;
4 | using System.Windows.Controls;
5 |
6 | ///
7 | /// Implements a look-less control that should function and look like a window (X) close button.
8 | ///
9 | public class NotificationCloseButton : Button
10 | {
11 | static NotificationCloseButton()
12 | {
13 | FrameworkElement.DefaultStyleKeyProperty.OverrideMetadata(typeof(NotificationCloseButton),
14 | new FrameworkPropertyMetadata(typeof(NotificationCloseButton)));
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/source/UserNotification/View/NotificationWindow.xaml:
--------------------------------------------------------------------------------
1 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
59 |
60 |
68 |
69 |
73 |
74 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/source/UserNotification/View/NotificationWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.View
2 | {
3 | using System.Windows;
4 | using System.Windows.Controls;
5 | using UserNotification.ViewModel;
6 |
7 | ///
8 | /// This class is used to view the content of a notification window.
9 | ///
10 | /// Based on: http://www.codeproject.com/Articles/499241/Growl-Alike-WPF-Notifications
11 | ///
12 | public partial class NotificationWindow : Window
13 | {
14 | #region constructor
15 | ///
16 | /// Class constructor
17 | ///
18 | public NotificationWindow()
19 | {
20 | this.CanClose = false;
21 |
22 | this.InitializeComponent();
23 | }
24 | #endregion constructor
25 |
26 | #region properties
27 | ///
28 | /// Determine whether window can be closed or whether closing
29 | /// via standard close functions should be cancelled in Closing override method.
30 | ///
31 | protected bool CanClose { get; set; }
32 | #endregion properties
33 |
34 | #region methods
35 | ///
36 | /// Is called by parent window to tell the window to close for good
37 | /// since parent view is also closing.
38 | ///
39 | public void CloseInvokedByParent()
40 | {
41 | this.CanClose = true;
42 | this.Close();
43 | }
44 |
45 | ///
46 | /// Overrides closing window behaviour to avoid that a user can close a notification
47 | /// via ALT+F4 or Esc key. Overiding this is required since a window that is closed
48 | /// cannot be shown via Show again - one would have to re-create the entire window
49 | /// with new - which is not part of the current concept.
50 | ///
51 | /// Current concept is: use Show/hide durring livetime of hosting window and close
52 | /// when hosting window is closed.
53 | ///
54 | ///
55 | protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
56 | {
57 | // Cancel closing notification window (since hidding should be used) until parent unloads
58 | // which will be notified via close through CloseInvokedByParent method
59 | if (this.CanClose == false)
60 | {
61 | e.Cancel = true;
62 | return;
63 | }
64 |
65 | base.OnClosing(e);
66 | }
67 |
68 | ///
69 | /// Show a new notification to the user.
70 | ///
71 | ///
72 | public void ShowNotification(NotificationViewModel notification)
73 | {
74 | ////Visually Debug this window with the color
75 | ////this.Background = new SolidColorBrush(Color.FromArgb(255,255,255,255));
76 |
77 | // Bind Window parameters (Width, Height, and TopMost)
78 | this.DataContext = notification;
79 |
80 | // Set content on control template
81 | this.NotificationsControl.Content = notification;
82 |
83 | if (!this.IsActive)
84 | this.Show();
85 | }
86 |
87 | ///
88 | /// Hide the notification window.
89 | ///
90 | public void HideNotification()
91 | {
92 | this.Hide();
93 | }
94 |
95 | ///
96 | /// This method is invoked via XAML code to tell the code behind
97 | /// that a notification is about to dissapper.
98 | ///
99 | ///
100 | ///
101 | private void NotificationWindowSizeChanged(object sender, SizeChangedEventArgs e)
102 | {
103 | if (e.NewSize.Height != 0.0)
104 | return;
105 |
106 | var element = sender as Grid;
107 |
108 | this.HideNotification();
109 | }
110 | #endregion methods
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/source/UserNotification/View/NotifyableContentControl.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.View
2 | {
3 | using System;
4 | using System.ComponentModel;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Media;
8 | using UserNotification.Interfaces;
9 | using UserNotification.ViewModel;
10 |
11 | ///
12 | /// This class implements a control that can be used to extend any standard control
13 | /// (eg: ListBox, TreeView) with a notification functionality. A notification is a
14 | /// small pop-up window that gives users feedback as to why somethings not working
15 | /// or what a user might be able to do to use a function correctly.
16 | ///
17 | /// This control is based on . Application developers
18 | /// can use this fact to contain any other standard control (say TextBox) inside this
19 | /// control. The Notification dependency property can then be used to show notifications
20 | /// in the vicinity of the contained control.
21 | ///
22 | /// This allows application developers to extend any control (eg: ListBox, TreeView)
23 | /// with a notification facility since application developers can invoke the
24 | /// ShowNotification event in the INotifyableViewModel interface to show a
25 | /// short pop-up message to the user. The pop-up message is shown in the
26 | /// vicinity of the content control that contains the real control (eg: ListBox)
27 | /// to which this notfication is related to.
28 | ///
29 | public class NotifyableContentControl : ContentControl
30 | {
31 | #region fields
32 | ///
33 | /// Gets/sets the notification dependency property that can be used to show
34 | /// user notification as pop-up object over the normal UI.
35 | ///
36 | public static readonly DependencyProperty NotificationProperty =
37 | DependencyProperty.Register("Notification",
38 | typeof(INotifyableViewModel),
39 | typeof(NotifyableContentControl),
40 | new FrameworkPropertyMetadata(null,
41 | new PropertyChangedCallback(OnNotificationChangedCallback)));
42 |
43 | private SimpleNotificationWindow mTip;
44 | private bool mDestroyNotificationOnFocusChange = false;
45 | private object mlockObject = new object();
46 |
47 | ///
48 | /// Is a viewmodel which keeps the command binding and event triggering to base the notifications on
49 | /// Using this setup tests the real world scenario where notifications are triggered through
50 | /// complex conditions in the viewmodel. These worklflows are not necessarily triggered by a button in a view.
51 | ///
52 | private INotifyableViewModel mViewModel;
53 | #endregion fields
54 |
55 | #region constructors
56 | ///
57 | /// Class constructor
58 | ///
59 | public NotifyableContentControl()
60 | {
61 | }
62 | #endregion constructors
63 |
64 | #region properties
65 | ///
66 | /// Gets/sets the notification dependency property that can be used to show
67 | /// user notification as pop-up object over the normal UI.
68 | ///
69 | [Category("Notification")]
70 | public INotifyableViewModel Notification
71 | {
72 | get { return (INotifyableViewModel)GetValue(NotificationProperty); }
73 | set { SetValue(NotificationProperty, value); }
74 | }
75 | #endregion properties
76 |
77 | #region methods
78 | private static void OnNotificationChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
79 | {
80 | var obj = d as NotifyableContentControl;
81 |
82 | if (obj != null)
83 | {
84 | obj.OnNofitivationChange(e.OldValue as INotifyableViewModel,
85 | e.NewValue as INotifyableViewModel);
86 | }
87 | }
88 |
89 | ///
90 | /// Method is invoked when the nofitivation dependency property is changed.
91 | /// This requires changing event hook-up on attached viewmodel to enable
92 | /// notification event conversion from viewmodel into view.
93 | ///
94 | ///
95 | ///
96 | private void OnNofitivationChange(INotifyableViewModel oldValue, INotifyableViewModel newValue)
97 | {
98 | if (this.mViewModel != null)
99 | {
100 | // Remove old link for showing notification pop-up message event
101 | this.mViewModel.ShowNotificationMessage -= ViewModel_ShowNotificationMessage;
102 | }
103 |
104 | this.mViewModel = newValue;
105 |
106 | if (this.mViewModel != null)
107 | {
108 | // Establish new link to show notification pop-up message event
109 | this.mViewModel.ShowNotificationMessage += ViewModel_ShowNotificationMessage;
110 | }
111 | }
112 |
113 | ///
114 | /// Method is invoked when the viewmodel tells the view: Show another notification to the user.
115 | ///
116 | ///
117 | ///
118 | private void ViewModel_ShowNotificationMessage(object sender, UserNotification.Events.ShowNotificationEvent e)
119 | {
120 | this.ShowNotification(e.Title, e.Message, true);
121 | }
122 |
123 | ///
124 | /// Shows a notification warning to the user to clarify the current application behavior.
125 | ///
126 | ///
127 | ///
128 | ///
129 | private void ShowNotification(string title, string message, bool notifiedFromViewmodel)
130 | {
131 | lock (this.mlockObject)
132 | {
133 | this.mDestroyNotificationOnFocusChange = notifiedFromViewmodel;
134 |
135 | if (this.mTip == null)
136 | {
137 | // Construct the notification window object to be shown to the user
138 | this.mTip = new SimpleNotificationWindow();
139 |
140 | var ownerWindow = this.GetDpObjectFromVisualTree(this, typeof(Window)) as Window;
141 | this.mTip.Owner = ownerWindow;
142 | }
143 |
144 | NotificationViewModel vm = new NotificationViewModel()
145 | {
146 | Title = title,
147 | Message = message,
148 | IsTopmost = false
149 | };
150 |
151 | this.mTip.ShowNotification(vm, this);
152 | }
153 | }
154 |
155 | ///
156 | /// Walk visual tree to find the first DependencyObject of a specific type.
157 | /// (This method works for finding a ScrollViewer within a TreeView).
158 | ///
159 | private DependencyObject GetDpObjectFromVisualTree(DependencyObject startObject, Type type)
160 | {
161 | // Walk the visual tree to get the parent(ItemsControl)
162 | // of this control
163 | DependencyObject parent = startObject;
164 | while (parent != null)
165 | {
166 | if (type.IsInstanceOfType(parent))
167 | break;
168 | else
169 | parent = VisualTreeHelper.GetParent(parent);
170 | }
171 |
172 | return parent;
173 | }
174 | #endregion methods
175 | }
176 | }
177 |
--------------------------------------------------------------------------------
/source/UserNotification/View/NotifyableWindow.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.View
2 | {
3 | using System;
4 | using System.Windows;
5 | using UserNotification.Interfaces;
6 | using UserNotification.ViewModel;
7 |
8 | ///
9 | /// Interaction logic for NotifyableWindow.xaml
10 | ///
11 | /// Based on:
12 | ///
13 | public partial class NotifyableWindow : Window
14 | {
15 | #region fields
16 | private const double TopOffset = 21;
17 | private const double LeftOffset = 0;
18 |
19 | // Is a window derived visual control class that shows the actual notification view
20 | readonly NotificationWindow notificationWindow = null;
21 |
22 | // Is a viewmodel which keeps the command binding and event triggering to base the notifications on
23 | // Using this setup tests the real world scenario where notifications are triggered through
24 | // complex conditions in the viewmodel. These worklflows are not necessarily triggered by a button in a view.
25 | private INotifyableViewModel mViewModel;
26 |
27 | private bool mAttachedNotificationEvent;
28 | #endregion fields
29 |
30 | #region constructors
31 | ///
32 | /// Class Constructor
33 | ///
34 | public NotifyableWindow()
35 | : base()
36 | {
37 | this.mAttachedNotificationEvent = false;
38 | this.notificationWindow = new NotificationWindow();
39 | this.DataContextChanged += MsgBoxView_DataContextChanged;
40 | this.Loaded += OnMsgBoxView_Loaded;
41 | this.Unloaded += NotifyableWindow_Unloaded;
42 | }
43 | #endregion constructors
44 |
45 | #region methods
46 | ///
47 | /// Method is invoked when the datacontext is changed.
48 | /// This requires changing event hook-up on attached viewmodel to enable
49 | /// notification event conversion from viewmodel into view.
50 | ///
51 | ///
52 | ///
53 | protected void MsgBoxView_DataContextChanged(object sender, System.Windows.DependencyPropertyChangedEventArgs e)
54 | {
55 | if (this.mAttachedNotificationEvent == true)
56 | this.mViewModel.ShowNotificationMessage -= ViewModel_ShowNotificationMessage;
57 |
58 | this.mViewModel = e.NewValue as INotifyableViewModel;
59 |
60 | if (this.mViewModel != null)
61 | {
62 | this.mViewModel.ShowNotificationMessage += ViewModel_ShowNotificationMessage;
63 | this.mAttachedNotificationEvent = true;
64 | }
65 | else
66 | this.mAttachedNotificationEvent = false;
67 | }
68 |
69 | ///
70 | /// Method is invoked when the viewmodel tells the view: Show another notification to the user.
71 | /// (override this method if you want to use a different viewmodel and custom (re-styled) notification view.
72 | ///
73 | ///
74 | ///
75 | protected void ViewModel_ShowNotificationMessage(object sender, UserNotification.Events.ShowNotificationEvent e)
76 | {
77 | NotificationViewModel vm = new UserNotification.ViewModel.NotificationViewModel
78 | {
79 | Title = e.Title,
80 | ImageIcon = e.ImageIcon,
81 | Message = e.Message
82 | };
83 |
84 | this.SetNextNotificationPosition(vm);
85 | this.notificationWindow.ShowNotification(vm);
86 | }
87 |
88 | ///
89 | /// Method is invoked to re-position the notification view such that it is close to the owning view.
90 | ///
91 | protected void SetNextNotificationPosition(NotificationViewModel vm)
92 | {
93 | double height = 125, width = 400;
94 |
95 | if (vm != null)
96 | {
97 | height = vm.ViewHeight;
98 | width = vm.ViewWidth;
99 | }
100 |
101 | // Attempt to position notification below close window (x) button
102 | this.notificationWindow.Top = this.Top + NotifyableWindow.TopOffset;
103 | this.notificationWindow.Left = this.Left + NotifyableWindow.LeftOffset +
104 | Math.Abs(this.Width - width);
105 |
106 | // Re-position notifiaction window if it appears to be outside of the visual screen
107 | // This works on primary screen [1 screen scenario] not sure if it works on 2 or more screens (?)
108 | if (this.notificationWindow.Top + height > SystemParameters.VirtualScreenHeight)
109 | this.notificationWindow.Top = SystemParameters.VirtualScreenHeight - height;
110 |
111 | if (this.notificationWindow.Left + width > SystemParameters.VirtualScreenWidth)
112 | this.notificationWindow.Left = SystemParameters.VirtualScreenWidth - width;
113 |
114 | if (this.notificationWindow.Top < SystemParameters.VirtualScreenTop)
115 | this.notificationWindow.Top = SystemParameters.VirtualScreenTop + 10;
116 |
117 | if (this.notificationWindow.Left < SystemParameters.VirtualScreenLeft)
118 | this.notificationWindow.Left = SystemParameters.VirtualScreenLeft + 10;
119 | }
120 |
121 | ///
122 | /// Method is invoked when the window is Loaded to set the notification owner property.
123 | ///
124 | ///
125 | ///
126 | protected void OnMsgBoxView_Loaded(object sender, RoutedEventArgs e)
127 | {
128 | //this will make minimize restore of notifications too
129 | this.notificationWindow.Owner = this;
130 | }
131 |
132 | ///
133 | /// Free notification resources when parent window is being closed.
134 | ///
135 | ///
136 | ///
137 | protected void NotifyableWindow_Unloaded(object sender, EventArgs e)
138 | {
139 | // Close notification window for good
140 | this.notificationWindow.CloseInvokedByParent();
141 |
142 | // Free event hook-up bewteen view and viewmodel
143 | if (this.mAttachedNotificationEvent == true)
144 | this.mViewModel.ShowNotificationMessage -= ViewModel_ShowNotificationMessage;
145 | }
146 | #endregion methods
147 | }
148 | }
149 |
--------------------------------------------------------------------------------
/source/UserNotification/View/SimpleNotificationWindow.xaml:
--------------------------------------------------------------------------------
1 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
38 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
55 |
56 |
58 |
59 |
73 |
74 |
78 |
79 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
113 |
120 |
121 |
122 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/source/UserNotification/View/SimpleNotificationWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.View
2 | {
3 | using System;
4 | using System.Windows;
5 | using System.Windows.Controls;
6 | using System.Windows.Media;
7 | using UserNotification.ViewModel;
8 |
9 | ///
10 | /// This class is used to view the content of a notification window.
11 | ///
12 | /// Based on: http://www.codeproject.com/Articles/499241/Growl-Alike-WPF-Notifications
13 | ///
14 | public partial class SimpleNotificationWindow : Window
15 | {
16 | #region constructor
17 | ///
18 | /// Class constructor
19 | ///
20 | public SimpleNotificationWindow()
21 | {
22 | this.CanClose = false;
23 |
24 | this.InitializeComponent();
25 | }
26 | #endregion constructor
27 |
28 | #region properties
29 | ///
30 | /// Determine whether window can be closed or whether closing
31 | /// via standard close functions should be cancelled in Closing override method.
32 | ///
33 | protected bool CanClose { get; set; }
34 | #endregion properties
35 |
36 | #region methods
37 | ///
38 | /// Is called by parent window to tell the window to close for good
39 | /// since parent view is also closing.
40 | ///
41 | public void CloseInvokedByParent()
42 | {
43 | this.CanClose = true;
44 | this.Close();
45 | }
46 |
47 | ///
48 | /// Overrides closing window behaviour to avoid that a user can close a notification
49 | /// via ALT+F4 or Esc key. Overiding this is required since a window that is closed
50 | /// cannot be shown via Show again - one would have to re-create the entire window
51 | /// with new - which is not part of the current concept.
52 | ///
53 | /// Current concept is: use Show/hide durring livetime of hosting window and close
54 | /// when hosting window is closed.
55 | ///
56 | ///
57 | protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
58 | {
59 | // Cancel closing notification window (since hidding should be used) until parent unloads
60 | // which will be notified via close through CloseInvokedByParent method
61 | if (this.CanClose == false)
62 | {
63 | e.Cancel = true;
64 | return;
65 | }
66 |
67 | base.OnClosing(e);
68 | }
69 |
70 | ///
71 | /// Method is invoked to re-position the notification view such that it is close to the owning view.
72 | ///
73 | protected void SetNextNotificationPosition(Visual view)
74 | {
75 | double height = 125, width = 400;
76 | const double topOffset = 21;
77 | const double leftOffset = 0;
78 |
79 | Point position = view.PointToScreen(new Point(0, 0));
80 |
81 | // Transform screen point to WPF device independent point
82 | PresentationSource source = PresentationSource.FromVisual(view);
83 |
84 | // https://social.msdn.microsoft.com/Forums/vstudio/de-DE/281a8cdd-69a9-4a4a-9fc3-c039119af8ed/absolute-screen-coordinates-of-wpf-user-control?forum=wpf
85 | Point targetPoints = source.CompositionTarget.TransformFromDevice.Transform(position);
86 |
87 | // Attempt to position notification below visual given to this function
88 | this.Top = targetPoints.Y + topOffset;
89 | this.Left = targetPoints.X + leftOffset;
90 |
91 | // Re-position notifiaction window if it appears to be outside of the visual screen
92 | // This works on primary screen [1 screen scenario] not sure if it works on 2 or more screens (?)
93 | //
94 | // Position above textbox instead of on lower corner of screen
95 | if (this.Top + height > SystemParameters.VirtualScreenHeight)
96 | this.Top = Math.Abs(position.Y - height);
97 |
98 | if (this.Left + width > SystemParameters.VirtualScreenWidth)
99 | this.Left = SystemParameters.VirtualScreenWidth - width;
100 |
101 | // Case should never occur since default position is below textblock
102 | if (this.Top < SystemParameters.VirtualScreenTop)
103 | this.Top = position.Y + topOffset;
104 |
105 | if (this.Left < SystemParameters.VirtualScreenLeft)
106 | this.Left = SystemParameters.VirtualScreenLeft + 10;
107 | }
108 |
109 | ///
110 | /// Show a new notification to the user.
111 | ///
112 | ///
113 | ///
114 | public void ShowNotification(NotificationViewModel notification, Visual view)
115 | {
116 | ////Visually Debug this window with the color
117 | ////this.Background = new SolidColorBrush(Color.FromArgb(255,255,255,255));
118 |
119 | // Bind Window parameters (Width, Height, and TopMost)
120 | this.DataContext = notification;
121 |
122 | // Set content on control template
123 | this.NotificationsControl.Content = notification;
124 | this.SetNextNotificationPosition(view);
125 |
126 | if (!this.IsActive)
127 | this.Show();
128 | }
129 |
130 | ///
131 | /// Hide the notification window.
132 | ///
133 | public void HideNotification()
134 | {
135 | this.Hide();
136 | }
137 |
138 | ///
139 | /// This method is invoked via XAML code to tell the code behind
140 | /// that a notification is about to dissapper.
141 | ///
142 | ///
143 | ///
144 | private void NotificationWindowSizeChanged(object sender, SizeChangedEventArgs e)
145 | {
146 | if (e.NewSize.Height != 0.0)
147 | return;
148 |
149 | var element = sender as Grid;
150 |
151 | this.HideNotification();
152 | }
153 | #endregion methods
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/source/UserNotification/ViewModel/Base/ViewModelBase.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.ViewModel.Base
2 | {
3 | using System;
4 | using System.ComponentModel;
5 | using System.Linq.Expressions;
6 |
7 | ///
8 | /// Implements the interface to supply
9 | /// a base for viewmodel classes in an MVVM pattern like application.
10 | ///
11 | public class ViewModelBase : INotifyPropertyChanged
12 | {
13 | ///
14 | /// Implements the property changed event of the interface.
15 | ///
16 | public event PropertyChangedEventHandler PropertyChanged;
17 |
18 | ///
19 | /// Tell bound controls (via WPF binding) to refresh their display.
20 | ///
21 | /// Sample call: this.NotifyPropertyChanged(() => this.IsSelected);
22 | /// where 'this' is derived from
23 | /// and IsSelected is a property.
24 | ///
25 | ///
26 | ///
27 | public void RaisePropertyChanged(Expression> property)
28 | {
29 | var lambda = (LambdaExpression)property;
30 | MemberExpression memberExpression;
31 |
32 | if (lambda.Body is UnaryExpression)
33 | {
34 | var unaryExpression = (UnaryExpression)lambda.Body;
35 | memberExpression = (MemberExpression)unaryExpression.Operand;
36 | }
37 | else
38 | memberExpression = (MemberExpression)lambda.Body;
39 |
40 | this.RaisePropertyChanged(memberExpression.Member.Name);
41 | }
42 |
43 | ///
44 | /// Base function to raise a property changed event for the given named property.
45 | ///
46 | /// Name of property to raise the event for.
47 | protected virtual void RaisePropertyChanged(string propertyName)
48 | {
49 | if (PropertyChanged != null)
50 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/source/UserNotification/ViewModel/NotificationViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.ViewModel
2 | {
3 | using System.ComponentModel;
4 | using System.Windows;
5 | using System.Windows.Media.Imaging;
6 |
7 | ///
8 | /// The notification viewmodel organized the backend logic necessary to show the
9 | /// information content for notifying users about something happening ...
10 | ///
11 | /// Based on: http://www.codeproject.com/Articles/499241/Growl-Alike-WPF-Notifications
12 | ///
13 | public class NotificationViewModel : Base.ViewModelBase
14 | {
15 | #region fiels
16 | private int id;
17 | private string mTitle;
18 | private string mMessage;
19 | private BitmapImage mImageIcon;
20 | private bool mIsTopmost;
21 | private double mHeight;
22 | private double mWidth;
23 | #endregion fiels
24 |
25 | #region constructor
26 | ///
27 | /// Class constructor
28 | ///
29 | public NotificationViewModel()
30 | {
31 | this.id = 0;
32 | this.mTitle = string.Empty;
33 | this.mMessage = string.Empty;
34 | this.mImageIcon = null;
35 |
36 | this.mIsTopmost = true;
37 | this.mHeight = 125;
38 | this.mWidth = 500;
39 |
40 | // This code is usefule for generating design-time sample code
41 | #if DEBUG
42 | DependencyObject dep = new DependencyObject();
43 | if (DesignerProperties.GetIsInDesignMode(dep) == true)
44 | {
45 | this.mTitle = "Sample title ...";
46 | this.mMessage = "This is a sample Message with a rather lomg boring text sample ..."; ;
47 | this.mImageIcon = null;
48 |
49 | this.mIsTopmost = true;
50 | this.mHeight = 125;
51 | this.mWidth = 500;
52 | }
53 |
54 | #endif
55 | }
56 | #endregion constructor
57 |
58 | #region properties
59 | ///
60 | /// Get/set notification id.
61 | ///
62 | public int Id
63 | {
64 | get { return id; }
65 |
66 | set
67 | {
68 | if (this.id == value)
69 | return;
70 |
71 | id = value;
72 | this.RaisePropertyChanged(() => this.Id);
73 | }
74 | }
75 |
76 | ///
77 | /// Get/set title of notification
78 | ///
79 | public string Title
80 | {
81 | get { return mTitle; }
82 |
83 | set
84 | {
85 | if (this.mTitle == value)
86 | return;
87 |
88 | this.mTitle = value;
89 | this.RaisePropertyChanged(() => this.Title);
90 | }
91 | }
92 |
93 | ///
94 | /// Get/set message of notification
95 | ///
96 | public string Message
97 | {
98 | get { return mMessage; }
99 |
100 | set
101 | {
102 | if (this.mMessage == value)
103 | return;
104 |
105 | this.mMessage = value;
106 | this.RaisePropertyChanged(() => this.Message);
107 | }
108 | }
109 |
110 | ///
111 | /// Get/set ImageUrl to (icon) image shown in the notification
112 | ///
113 | public BitmapImage ImageIcon
114 | {
115 | get { return mImageIcon; }
116 |
117 | set
118 | {
119 | if (this.mImageIcon == value)
120 | return;
121 |
122 | this.mImageIcon = value;
123 | this.RaisePropertyChanged(() => this.ImageIcon);
124 | }
125 | }
126 |
127 | ///
128 | /// Get/set property to determine whether notification
129 | /// is shown in a topmost window or not.
130 | ///
131 | public bool IsTopmost
132 | {
133 | get
134 | {
135 | return this.mIsTopmost;
136 | }
137 |
138 | set
139 | {
140 | if (this.mIsTopmost != value)
141 | {
142 | this.mIsTopmost = value;
143 | this.RaisePropertyChanged(() => this.IsTopmost);
144 | }
145 | }
146 | }
147 |
148 | ///
149 | /// Get/set height of view that displays the notification.
150 | ///
151 | public double ViewHeight
152 | {
153 | get
154 | {
155 | return this.mHeight;
156 | }
157 |
158 | set
159 | {
160 | if (this.mHeight != value)
161 | {
162 | this.mHeight = value;
163 | this.RaisePropertyChanged(() => this.ViewHeight);
164 | }
165 | }
166 | }
167 |
168 | ///
169 | /// Get/set width of view that displays the notification.
170 | ///
171 | public double ViewWidth
172 | {
173 | get
174 | {
175 | return this.mWidth;
176 | }
177 |
178 | set
179 | {
180 | if (this.mWidth != value)
181 | {
182 | this.mWidth = value;
183 | this.RaisePropertyChanged(() => this.ViewWidth);
184 | }
185 | }
186 | }
187 | #endregion properties
188 | }
189 | }
--------------------------------------------------------------------------------
/source/UserNotification/ViewModel/SendNotificationViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotification.ViewModel
2 | {
3 | using System.Windows.Media.Imaging;
4 | using UserNotification.Events;
5 | using UserNotification.Interfaces;
6 |
7 | ///
8 | /// Implements the viewmodel events and methods to send a notification to an attached view.
9 | ///
10 | public class SendNotificationViewModel : Base.ViewModelBase, INotifyableViewModel
11 | {
12 |
13 | #region events
14 | ///
15 | /// Standard notifiaction event of
16 | ///
17 | public event UserNotification.Events.ShowNotificationEventHandler ShowNotificationMessage;
18 | #endregion events
19 |
20 | #region methods
21 | ///
22 | /// Sends a notification event to a view which will display a corresponding message, if any
23 | /// view has subscribed to the event in this object.
24 | ///
25 | ///
26 | ///
27 | ///
28 | /// true if notifiaction was successfully send (view is attached to event)
29 | /// or , otherwise, false
30 | public bool ShowNotification(string title, string message, BitmapImage imageIcon = null)
31 | {
32 | // Invoke another notification event to tell the view: Lets display another notification.
33 | if (this.ShowNotificationMessage != null)
34 | {
35 | this.ShowNotificationMessage(this, new ShowNotificationEvent
36 | (
37 | title,
38 | message,
39 | imageIcon
40 | ));
41 |
42 | return true;
43 | }
44 |
45 | return false;
46 | }
47 | #endregion methods
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/source/UserNotificationDemo/App.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/source/UserNotificationDemo/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Configuration;
4 | using System.Linq;
5 | using System.Windows;
6 |
7 | namespace UserNotificationDemo
8 | {
9 | ///
10 | /// Interaction logic for App.xaml
11 | ///
12 | public partial class App : Application
13 | {
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/source/UserNotificationDemo/Command/RelayCommand.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotificationDemo.Commands
2 | {
3 | using System;
4 | using System.Diagnostics;
5 | using System.Windows.Input;
6 |
7 | ///
8 | /// A command whose sole purpose is to
9 | /// relay its functionality to other
10 | /// objects by invoking delegates. The
11 | /// default return value for the CanExecute
12 | /// method is 'true'.
13 | ///
14 | /// Source: http://www.codeproject.com/Articles/31837/Creating-an-Internationalized-Wizard-in-WPF
15 | ///
16 | internal class RelayCommand : ICommand
17 | {
18 | #region Fields
19 | private readonly Action mExecute = null;
20 | private readonly Predicate mCanExecute = null;
21 | #endregion // Fields
22 |
23 | #region Constructors
24 | ///
25 | /// Class constructor
26 | ///
27 | ///
28 | public RelayCommand(Action execute)
29 | : this(execute, null)
30 | {
31 | }
32 |
33 | ///
34 | /// Creates a new command.
35 | ///
36 | /// The execution logic.
37 | /// The execution status logic.
38 | public RelayCommand(Action execute, Predicate canExecute)
39 | {
40 | if (execute == null)
41 | throw new ArgumentNullException("execute");
42 |
43 | this.mExecute = execute;
44 | this.mCanExecute = canExecute;
45 | }
46 |
47 | #endregion // Constructors
48 |
49 | #region events
50 | ///
51 | /// Eventhandler to re-evaluate whether this command can execute or not
52 | ///
53 | public event EventHandler CanExecuteChanged
54 | {
55 | add
56 | {
57 | if (this.mCanExecute != null)
58 | CommandManager.RequerySuggested += value;
59 | }
60 |
61 | remove
62 | {
63 | if (this.mCanExecute != null)
64 | CommandManager.RequerySuggested -= value;
65 | }
66 | }
67 | #endregion
68 |
69 | #region methods
70 | ///
71 | /// Determine whether this pre-requisites to execute this command are given or not.
72 | ///
73 | ///
74 | ///
75 | [DebuggerStepThrough]
76 | public bool CanExecute(object parameter)
77 | {
78 | return this.mCanExecute == null ? true : this.mCanExecute((T)parameter);
79 | }
80 |
81 | ///
82 | /// Execute the command method managed in this class.
83 | ///
84 | ///
85 | public void Execute(object parameter)
86 | {
87 | this.mExecute((T)parameter);
88 | }
89 | #endregion methods
90 | }
91 |
92 | ///
93 | /// A command whose sole purpose is to
94 | /// relay its functionality to other
95 | /// objects by invoking delegates. The
96 | /// default return value for the CanExecute
97 | /// method is 'true'.
98 | ///
99 | internal class RelayCommand : ICommand
100 | {
101 | #region Fields
102 | private readonly Action mExecute;
103 | private readonly Func mCanExecute;
104 | #endregion Fields
105 |
106 | #region Constructors
107 |
108 | ///
109 | /// Creates a new command that can always execute.
110 | ///
111 | /// The execution logic.
112 | public RelayCommand(Action execute)
113 | : this(execute, null)
114 | {
115 | }
116 |
117 | ///
118 | /// Copy constructor
119 | ///
120 | ///
121 | public RelayCommand(RelayCommand inputRC)
122 | : this(inputRC.mExecute, inputRC.mCanExecute)
123 | {
124 | }
125 |
126 | ///
127 | /// Creates a new command.
128 | ///
129 | /// The execution logic.
130 | /// The execution status logic.
131 | public RelayCommand(Action execute, Func canExecute)
132 | {
133 | if (execute == null)
134 | throw new ArgumentNullException("execute");
135 |
136 | this.mExecute = execute;
137 | this.mCanExecute = canExecute;
138 | }
139 |
140 | #endregion Constructors
141 |
142 | #region Events
143 | ///
144 | /// Eventhandler to re-evaluate whether this command can execute or not
145 | ///
146 | public event EventHandler CanExecuteChanged
147 | {
148 | add
149 | {
150 | if (this.mCanExecute != null)
151 | CommandManager.RequerySuggested += value;
152 | }
153 |
154 | remove
155 | {
156 | if (this.mCanExecute != null)
157 | CommandManager.RequerySuggested -= value;
158 | }
159 | }
160 | #endregion Events
161 |
162 | #region Methods
163 | ///
164 | /// Execute the attached CanExecute methode delegate (or always return true)
165 | /// to determine whether the command managed in this object can execute or not.
166 | ///
167 | ///
168 | ///
169 | [DebuggerStepThrough]
170 | public bool CanExecute(object parameter)
171 | {
172 | return this.mCanExecute == null ? true : this.mCanExecute();
173 | }
174 |
175 | ///
176 | /// Return the attached delegate method.
177 | ///
178 | ///
179 | public void Execute(object parameter)
180 | {
181 | this.mExecute();
182 | }
183 | #endregion Methods
184 | }
185 | }
186 |
--------------------------------------------------------------------------------
/source/UserNotificationDemo/Resources/Radiation_warning_symbol.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotificationDemo/Resources/Radiation_warning_symbol.png
--------------------------------------------------------------------------------
/source/UserNotificationDemo/Resources/facebook-button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotificationDemo/Resources/facebook-button.png
--------------------------------------------------------------------------------
/source/UserNotificationDemo/Resources/microsoft-windows-8-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotificationDemo/Resources/microsoft-windows-8-logo.png
--------------------------------------------------------------------------------
/source/UserNotificationDemo/Resources/notification-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dirkster99/UserNotifications/d3fca068031aef1571f46f5afe0fc707c13ff143/source/UserNotificationDemo/Resources/notification-icon.png
--------------------------------------------------------------------------------
/source/UserNotificationDemo/UserNotificationDemo.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | WinExe
5 | net45;netcoreapp3.0
6 | true
7 |
8 |
9 |
10 | WPFNotifications
11 | WPFNotifications
12 | Copyright © 2012
13 | Open Source
14 | https://github.com/Dirkster99/Edi
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
35 |
--------------------------------------------------------------------------------
/source/UserNotificationDemo/UserNotificationDemo.csproj.user:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | netcoreapp3.0
5 |
6 |
--------------------------------------------------------------------------------
/source/UserNotificationDemo/ViewModels/Base/ViewModelBase.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotificationDemo.ViewModels.Base
2 | {
3 | using System;
4 | using System.ComponentModel;
5 | using System.Linq.Expressions;
6 |
7 | public class ViewModelBase : INotifyPropertyChanged
8 | {
9 | ///
10 | /// Implements the property changed event of the interface.
11 | ///
12 | public event PropertyChangedEventHandler PropertyChanged;
13 |
14 | ///
15 | /// Tell bound controls (via WPF binding) to refresh their display.
16 | ///
17 | /// Sample call: this.NotifyPropertyChanged(() => this.IsSelected);
18 | /// where 'this' is derived from
19 | /// and IsSelected is a property.
20 | ///
21 | ///
22 | ///
23 | public void RaisePropertyChanged(Expression> property)
24 | {
25 | var lambda = (LambdaExpression)property;
26 | MemberExpression memberExpression;
27 |
28 | if (lambda.Body is UnaryExpression)
29 | {
30 | var unaryExpression = (UnaryExpression)lambda.Body;
31 | memberExpression = (MemberExpression)unaryExpression.Operand;
32 | }
33 | else
34 | memberExpression = (MemberExpression)lambda.Body;
35 |
36 | this.RaisePropertyChanged(memberExpression.Member.Name);
37 | }
38 |
39 | protected virtual void RaisePropertyChanged(string propertyName)
40 | {
41 | if (PropertyChanged != null)
42 | PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
43 | }
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/source/UserNotificationDemo/ViewModels/TestNotifyableContentControlViewModel.cs:
--------------------------------------------------------------------------------
1 | namespace UserNotificationDemo.ViewModels
2 | {
3 | using System.Collections.ObjectModel;
4 | using System.Windows.Input;
5 | using UserNotification.ViewModel;
6 | using UserNotificationDemo.Commands;
7 |
8 | ///
9 | /// Implement a test viewmodel class for driving the
10 | /// .
11 | ///
12 | public class TestNotifyableContentControlViewModel : Base.ViewModelBase
13 | {
14 | #region fields
15 | private RelayCommand