123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722 |
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Linq;
- using System.Runtime.InteropServices;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Controls.Primitives;
- using System.Windows.Data;
- using System.Windows.Input;
- using System.Windows.Media;
- using System.Windows.Threading;
- using HandyControl.Data;
- using HandyControl.Tools;
- using HandyControl.Tools.Interop;
- namespace HandyControl.Controls;
- public class NotifyIcon : FrameworkElement, IDisposable
- {
- private bool _isMouseOver;
- private bool _added;
- private readonly object _syncObj = new();
- private readonly int _id;
- private ImageSource _icon;
- private IntPtr _iconCurrentHandle;
- private IntPtr _iconDefaultHandle;
- private IconHandle _iconHandle;
- private const int WmTrayMouseMessage = InteropValues.WM_USER + 1024;
- private string _windowClassName;
- private int _wmTaskbarCreated;
- private IntPtr _messageWindowHandle;
- private readonly InteropValues.WndProc _callback;
- private Popup _contextContent;
- private bool _doubleClick;
- private DispatcherTimer _dispatcherTimerBlink;
- private DispatcherTimer _dispatcherTimerPos;
- private bool _isTransparent;
- private bool _isDisposed;
- private static int NextId;
- private static readonly Dictionary<string, NotifyIcon> NotifyIconDic = new();
- static NotifyIcon()
- {
- VisibilityProperty.OverrideMetadata(typeof(NotifyIcon), new PropertyMetadata(Visibility.Visible, OnVisibilityChanged));
- DataContextProperty.OverrideMetadata(typeof(NotifyIcon), new FrameworkPropertyMetadata(DataContextPropertyChanged));
- ContextMenuProperty.OverrideMetadata(typeof(NotifyIcon), new FrameworkPropertyMetadata(ContextMenuPropertyChanged));
- }
- private static void OnVisibilityChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var ctl = (NotifyIcon) d;
- var v = (Visibility) e.NewValue;
- if (v == Visibility.Visible)
- {
- if (ctl._iconCurrentHandle == IntPtr.Zero)
- {
- ctl.OnIconChanged();
- }
- ctl.UpdateIcon(true);
- }
- else if (ctl._iconCurrentHandle != IntPtr.Zero)
- {
- ctl.UpdateIcon(false);
- }
- }
- private static void DataContextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) =>
- ((NotifyIcon) d).OnDataContextPropertyChanged(e);
- private void OnDataContextPropertyChanged(DependencyPropertyChangedEventArgs e)
- {
- UpdateDataContext(_contextContent, e.OldValue, e.NewValue);
- UpdateDataContext(ContextMenu, e.OldValue, e.NewValue);
- }
- private static void ContextMenuPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var ctl = (NotifyIcon) d;
- ctl.OnContextMenuPropertyChanged(e);
- }
- private void OnContextMenuPropertyChanged(DependencyPropertyChangedEventArgs e) =>
- UpdateDataContext((ContextMenu) e.NewValue, null, DataContext);
- public NotifyIcon()
- {
- _id = ++NextId;
- _callback = Callback;
- Loaded += (s, e) => Init();
- if (Application.Current != null) Application.Current.Exit += (s, e) => Dispose();
- }
- ~NotifyIcon() => Dispose(false);
- public void Init()
- {
- RegisterClass();
- if (Visibility == Visibility.Visible)
- {
- OnIconChanged();
- UpdateIcon(true);
- }
- _dispatcherTimerPos = new DispatcherTimer
- {
- Interval = TimeSpan.FromMilliseconds(200)
- };
- _dispatcherTimerPos.Tick += DispatcherTimerPos_Tick;
- }
- public static void Register(string token, NotifyIcon notifyIcon)
- {
- if (string.IsNullOrEmpty(token) || notifyIcon == null) return;
- NotifyIconDic[token] = notifyIcon;
- }
- public static void Unregister(string token, NotifyIcon notifyIcon)
- {
- if (string.IsNullOrEmpty(token) || notifyIcon == null) return;
- if (NotifyIconDic.ContainsKey(token))
- {
- if (ReferenceEquals(NotifyIconDic[token], notifyIcon))
- {
- NotifyIconDic.Remove(token);
- }
- }
- }
- public static void Unregister(NotifyIcon notifyIcon)
- {
- if (notifyIcon == null) return;
- var first = NotifyIconDic.FirstOrDefault(item => ReferenceEquals(notifyIcon, item.Value));
- if (!string.IsNullOrEmpty(first.Key))
- {
- NotifyIconDic.Remove(first.Key);
- }
- }
- public static void Unregister(string token)
- {
- if (string.IsNullOrEmpty(token)) return;
- if (NotifyIconDic.ContainsKey(token))
- {
- NotifyIconDic.Remove(token);
- }
- }
- public static void ShowBalloonTip(string title, string content, NotifyIconInfoType infoType, string token)
- {
- if (NotifyIconDic.TryGetValue(token, out var notifyIcon))
- {
- notifyIcon.ShowBalloonTip(title, content, infoType);
- }
- }
- public void ShowBalloonTip(string title, string content, NotifyIconInfoType infoType)
- {
- if (!_added || DesignerHelper.IsInDesignMode) return;
- var data = new InteropValues.NOTIFYICONDATA
- {
- uFlags = InteropValues.NIF_INFO,
- hWnd = _messageWindowHandle,
- uID = _id,
- szInfoTitle = title ?? string.Empty,
- szInfo = content ?? string.Empty
- };
- data.dwInfoFlags = infoType switch
- {
- NotifyIconInfoType.Info => InteropValues.NIIF_INFO,
- NotifyIconInfoType.Warning => InteropValues.NIIF_WARNING,
- NotifyIconInfoType.Error => InteropValues.NIIF_ERROR,
- NotifyIconInfoType.None => InteropValues.NIIF_NONE,
- _ => data.dwInfoFlags
- };
- InteropMethods.Shell_NotifyIcon(InteropValues.NIM_MODIFY, data);
- }
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
- public void CloseContextControl()
- {
- if (_contextContent != null)
- {
- _contextContent.IsOpen = false;
- }
- else if (ContextMenu != null)
- {
- ContextMenu.IsOpen = false;
- }
- }
- public static readonly DependencyProperty TokenProperty = DependencyProperty.Register(
- nameof(Token), typeof(string), typeof(NotifyIcon), new PropertyMetadata(default(string), OnTokenChanged));
- private static void OnTokenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- if (d is NotifyIcon notifyIcon)
- {
- if (e.NewValue == null)
- {
- Unregister(notifyIcon);
- }
- else
- {
- Register(e.NewValue.ToString(), notifyIcon);
- }
- }
- }
- public string Token
- {
- get => (string) GetValue(TokenProperty);
- set => SetValue(TokenProperty, value);
- }
- public static readonly DependencyProperty TextProperty = DependencyProperty.Register(
- nameof(Text), typeof(string), typeof(NotifyIcon), new PropertyMetadata(default(string)));
- public string Text
- {
- get => (string) GetValue(TextProperty);
- set => SetValue(TextProperty, value);
- }
- public static readonly DependencyProperty IconProperty = DependencyProperty.Register(
- nameof(Icon), typeof(ImageSource), typeof(NotifyIcon), new PropertyMetadata(default(ImageSource), OnIconChanged));
- private static void OnIconChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var ctl = (NotifyIcon) d;
- ctl._icon = (ImageSource) e.NewValue;
- ctl.OnIconChanged();
- if (!string.IsNullOrEmpty(ctl._windowClassName) && !ctl.IsBlink && ctl.Visibility == Visibility.Visible)
- {
- ctl.UpdateIcon(true);
- }
- }
- public ImageSource Icon
- {
- get => (ImageSource) GetValue(IconProperty);
- set => SetValue(IconProperty, value);
- }
- public static readonly DependencyProperty ContextContentProperty = DependencyProperty.Register(
- nameof(ContextContent), typeof(object), typeof(NotifyIcon), new PropertyMetadata(default(object)));
- public object ContextContent
- {
- get => GetValue(ContextContentProperty);
- set => SetValue(ContextContentProperty, value);
- }
- public static readonly DependencyProperty BlinkIntervalProperty = DependencyProperty.Register(
- nameof(BlinkInterval), typeof(TimeSpan), typeof(NotifyIcon), new PropertyMetadata(TimeSpan.FromMilliseconds(500), OnBlinkIntervalChanged));
- private static void OnBlinkIntervalChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var ctl = (NotifyIcon) d;
- if (ctl._dispatcherTimerBlink != null)
- {
- ctl._dispatcherTimerBlink.Interval = (TimeSpan) e.NewValue;
- }
- }
- public TimeSpan BlinkInterval
- {
- get => (TimeSpan) GetValue(BlinkIntervalProperty);
- set => SetValue(BlinkIntervalProperty, value);
- }
- public static readonly DependencyProperty IsBlinkProperty = DependencyProperty.Register(
- nameof(IsBlink), typeof(bool), typeof(NotifyIcon), new PropertyMetadata(ValueBoxes.FalseBox, OnIsBlinkChanged));
- private static void OnIsBlinkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
- {
- var ctl = (NotifyIcon) d;
- if (ctl.Visibility != Visibility.Visible) return;
- if ((bool) e.NewValue)
- {
- if (ctl._dispatcherTimerBlink == null)
- {
- ctl._dispatcherTimerBlink = new DispatcherTimer
- {
- Interval = ctl.BlinkInterval
- };
- ctl._dispatcherTimerBlink.Tick += ctl.DispatcherTimerBlinkTick;
- }
- ctl._dispatcherTimerBlink.Start();
- }
- else
- {
- ctl._dispatcherTimerBlink?.Stop();
- ctl._dispatcherTimerBlink = null;
- ctl.UpdateIcon(true);
- }
- }
- public bool IsBlink
- {
- get => (bool) GetValue(IsBlinkProperty);
- set => SetValue(IsBlinkProperty, ValueBoxes.BooleanBox(value));
- }
- private void DispatcherTimerBlinkTick(object sender, EventArgs e)
- {
- if (Visibility != Visibility.Visible || _iconCurrentHandle == IntPtr.Zero) return;
- UpdateIcon(true, !_isTransparent);
- }
- private bool CheckMouseIsEnter()
- {
- var isTrue = FindNotifyIcon(out var rectNotifyList);
- if (!isTrue) return false;
- InteropMethods.GetCursorPos(out var point);
- return rectNotifyList.Any(rectNotify =>
- point.X >= rectNotify.Left &&
- point.X <= rectNotify.Right &&
- point.Y >= rectNotify.Top &&
- point.Y <= rectNotify.Bottom);
- }
- private void DispatcherTimerPos_Tick(object sender, EventArgs e)
- {
- if (CheckMouseIsEnter())
- {
- if (!_isMouseOver)
- {
- _isMouseOver = true;
- RaiseEvent(new MouseEventArgs(Mouse.PrimaryDevice, Environment.TickCount)
- {
- RoutedEvent = MouseEnterEvent
- });
- _dispatcherTimerPos.Interval = TimeSpan.FromMilliseconds(500);
- }
- }
- else
- {
- _dispatcherTimerPos.Stop();
- _isMouseOver = false;
- RaiseEvent(new MouseEventArgs(Mouse.PrimaryDevice, Environment.TickCount)
- {
- RoutedEvent = MouseLeaveEvent
- });
- }
- }
- //referenced from http://www.cnblogs.com/sczmzx/p/5158127.html
- private IntPtr FindTrayToolbarWindow()
- {
- var hWnd = InteropMethods.FindWindow("Shell_TrayWnd", null);
- if (hWnd != IntPtr.Zero)
- {
- hWnd = InteropMethods.FindWindowEx(hWnd, IntPtr.Zero, "TrayNotifyWnd", null);
- if (hWnd != IntPtr.Zero)
- {
- hWnd = InteropMethods.FindWindowEx(hWnd, IntPtr.Zero, "SysPager", null);
- if (hWnd != IntPtr.Zero)
- {
- hWnd = InteropMethods.FindWindowEx(hWnd, IntPtr.Zero, "ToolbarWindow32", null);
- }
- }
- }
- return hWnd;
- }
- //referenced from http://www.cnblogs.com/sczmzx/p/5158127.html
- private IntPtr FindTrayToolbarOverFlowWindow()
- {
- var hWnd = InteropMethods.FindWindow("NotifyIconOverflowWindow", null);
- if (hWnd != IntPtr.Zero)
- {
- hWnd = InteropMethods.FindWindowEx(hWnd, IntPtr.Zero, "ToolbarWindow32", null);
- }
- return hWnd;
- }
- private bool FindNotifyIcon(out List<InteropValues.RECT> rectList)
- {
- var rectNotifyList = new List<InteropValues.RECT>();
- var hTrayWnd = FindTrayToolbarWindow();
- var isTrue = FindNotifyIcon(hTrayWnd, ref rectNotifyList);
- if (!isTrue)
- {
- hTrayWnd = FindTrayToolbarOverFlowWindow();
- isTrue = FindNotifyIcon(hTrayWnd, ref rectNotifyList);
- }
- rectList = rectNotifyList;
- return isTrue;
- }
- //referenced from http://www.cnblogs.com/sczmzx/p/5158127.html
- private bool FindNotifyIcon(IntPtr hTrayWnd, ref List<InteropValues.RECT> rectNotifyList)
- {
- InteropMethods.GetWindowRect(hTrayWnd, out var rectTray);
- var count = (int) InteropMethods.SendMessage(hTrayWnd, InteropValues.TB_BUTTONCOUNT, 0, IntPtr.Zero);
- var isFind = false;
- if (count > 0)
- {
- InteropMethods.GetWindowThreadProcessId(hTrayWnd, out var trayPid);
- var hProcess = InteropMethods.OpenProcess(InteropValues.ProcessAccess.VMOperation | InteropValues.ProcessAccess.VMRead | InteropValues.ProcessAccess.VMWrite, false, trayPid);
- var address = InteropMethods.VirtualAllocEx(hProcess, IntPtr.Zero, 1024, InteropValues.AllocationType.Commit, InteropValues.MemoryProtection.ReadWrite);
- var btnData = new InteropValues.TBBUTTON();
- var trayData = new InteropValues.TRAYDATA();
- var handle = Process.GetCurrentProcess().Id;
- for (uint i = 0; i < count; i++)
- {
- InteropMethods.SendMessage(hTrayWnd, InteropValues.TB_GETBUTTON, i, address);
- var isTrue = InteropMethods.ReadProcessMemory(hProcess, address, out btnData, Marshal.SizeOf(btnData), out _);
- if (!isTrue) continue;
- if (btnData.dwData == IntPtr.Zero)
- {
- btnData.dwData = btnData.iString;
- }
- InteropMethods.ReadProcessMemory(hProcess, btnData.dwData, out trayData, Marshal.SizeOf(trayData), out _);
- InteropMethods.GetWindowThreadProcessId(trayData.hwnd, out var dwProcessId);
- if (dwProcessId == (uint) handle)
- {
- var rect = new InteropValues.RECT();
- var lngRect = InteropMethods.VirtualAllocEx(hProcess, IntPtr.Zero, Marshal.SizeOf(typeof(Rect)), InteropValues.AllocationType.Commit, InteropValues.MemoryProtection.ReadWrite);
- InteropMethods.SendMessage(hTrayWnd, InteropValues.TB_GETITEMRECT, i, lngRect);
- InteropMethods.ReadProcessMemory(hProcess, lngRect, out rect, Marshal.SizeOf(rect), out _);
- InteropMethods.VirtualFreeEx(hProcess, lngRect, Marshal.SizeOf(rect), InteropValues.FreeType.Decommit);
- InteropMethods.VirtualFreeEx(hProcess, lngRect, 0, InteropValues.FreeType.Release);
- var left = rectTray.Left + rect.Left;
- var top = rectTray.Top + rect.Top;
- var botton = rectTray.Top + rect.Bottom;
- var right = rectTray.Left + rect.Right;
- rectNotifyList.Add(new InteropValues.RECT
- {
- Left = left,
- Right = right,
- Top = top,
- Bottom = botton
- });
- isFind = true;
- }
- }
- InteropMethods.VirtualFreeEx(hProcess, address, 0x4096, InteropValues.FreeType.Decommit);
- InteropMethods.VirtualFreeEx(hProcess, address, 0, InteropValues.FreeType.Release);
- InteropMethods.CloseHandle(hProcess);
- }
- return isFind;
- }
- private void OnIconChanged()
- {
- if (_windowClassName == null) return;
- if (_icon != null)
- {
- IconHelper.GetIconHandlesFromImageSource(_icon, out _, out _iconHandle);
- _iconCurrentHandle = _iconHandle.CriticalGetHandle();
- }
- else
- {
- if (_iconDefaultHandle == IntPtr.Zero)
- {
- IconHelper.GetDefaultIconHandles(out _, out _iconHandle);
- _iconDefaultHandle = _iconHandle.CriticalGetHandle();
- }
- _iconCurrentHandle = _iconDefaultHandle;
- }
- }
- private void UpdateIcon(bool showIconInTray, bool isTransparent = false)
- {
- lock (_syncObj)
- {
- if (DesignerHelper.IsInDesignMode) return;
- _isTransparent = isTransparent;
- var data = new InteropValues.NOTIFYICONDATA
- {
- uCallbackMessage = WmTrayMouseMessage,
- uFlags = InteropValues.NIF_MESSAGE | InteropValues.NIF_ICON | InteropValues.NIF_TIP,
- hWnd = _messageWindowHandle,
- uID = _id,
- dwInfoFlags = InteropValues.NIF_TIP,
- hIcon = isTransparent ? IntPtr.Zero : _iconCurrentHandle,
- szTip = Text
- };
- if (showIconInTray)
- {
- if (!_added)
- {
- InteropMethods.Shell_NotifyIcon(InteropValues.NIM_ADD, data);
- _added = true;
- }
- else
- {
- InteropMethods.Shell_NotifyIcon(InteropValues.NIM_MODIFY, data);
- }
- }
- else if (_added)
- {
- InteropMethods.Shell_NotifyIcon(InteropValues.NIM_DELETE, data);
- _added = false;
- }
- }
- }
- private void RegisterClass()
- {
- _windowClassName = $"HandyControl.Controls.NotifyIcon{Guid.NewGuid()}";
- var wndclass = new InteropValues.WNDCLASS4ICON
- {
- style = 0,
- lpfnWndProc = _callback,
- cbClsExtra = 0,
- cbWndExtra = 0,
- hInstance = IntPtr.Zero,
- hIcon = IntPtr.Zero,
- hCursor = IntPtr.Zero,
- hbrBackground = IntPtr.Zero,
- lpszMenuName = "",
- lpszClassName = _windowClassName
- };
- InteropMethods.RegisterClass(wndclass);
- _wmTaskbarCreated = InteropMethods.RegisterWindowMessage("TaskbarCreated");
- _messageWindowHandle = InteropMethods.CreateWindowEx(0, _windowClassName, "", 0, 0, 0, 1, 1,
- IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
- }
- private IntPtr Callback(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam)
- {
- if (msg == _wmTaskbarCreated)
- {
- if (_messageWindowHandle == hWnd && Visibility == Visibility.Visible)
- {
- UpdateIcon(false);
- UpdateIcon(true);
- }
- }
- else
- {
- switch (lparam.ToInt64())
- {
- case InteropValues.WM_LBUTTONDBLCLK:
- WmMouseDown(MouseButton.Left, 2);
- break;
- case InteropValues.WM_LBUTTONUP:
- WmMouseUp(MouseButton.Left);
- break;
- case InteropValues.WM_RBUTTONUP:
- ShowContextMenu();
- WmMouseUp(MouseButton.Right);
- break;
- case InteropValues.WM_MOUSEMOVE:
- if (!_dispatcherTimerPos.IsEnabled)
- {
- _dispatcherTimerPos.Interval = TimeSpan.FromMilliseconds(200);
- _dispatcherTimerPos.Start();
- }
- break;
- }
- }
- return InteropMethods.DefWindowProc(hWnd, msg, wparam, lparam);
- }
- private void WmMouseDown(MouseButton button, int clicks)
- {
- if (clicks == 2)
- {
- RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
- {
- RoutedEvent = MouseDoubleClickEvent
- });
- _doubleClick = true;
- }
- }
- private void WmMouseUp(MouseButton button)
- {
- if (!_doubleClick && button == MouseButton.Left)
- {
- RaiseEvent(new MouseButtonEventArgs(Mouse.PrimaryDevice, Environment.TickCount, button)
- {
- RoutedEvent = ClickEvent
- });
- }
- _doubleClick = false;
- }
- private void ShowContextMenu()
- {
- if (ContextContent != null)
- {
- _contextContent ??= new Popup
- {
- Placement = PlacementMode.Mouse,
- AllowsTransparency = true,
- StaysOpen = false,
- UseLayoutRounding = true,
- SnapsToDevicePixels = true
- };
- _contextContent.Child = new ContentControl
- {
- Content = ContextContent
- };
- _contextContent.IsOpen = true;
- InteropMethods.SetForegroundWindow(_contextContent.Child.GetHandle());
- }
- else if (ContextMenu != null)
- {
- if (ContextMenu.Items.Count == 0) return;
- ContextMenu.InvalidateProperty(StyleProperty);
- foreach (var item in ContextMenu.Items)
- {
- if (item is MenuItem menuItem)
- {
- menuItem.InvalidateProperty(StyleProperty);
- }
- else
- {
- var container = ContextMenu.ItemContainerGenerator.ContainerFromItem(item) as MenuItem;
- container?.InvalidateProperty(StyleProperty);
- }
- }
- ContextMenu.Placement = PlacementMode.Mouse;
- ContextMenu.IsOpen = true;
- InteropMethods.SetForegroundWindow(ContextMenu.GetHandle());
- }
- }
- public static readonly RoutedEvent ClickEvent =
- EventManager.RegisterRoutedEvent("Click", RoutingStrategy.Bubble,
- typeof(RoutedEventHandler), typeof(NotifyIcon));
- public event RoutedEventHandler Click
- {
- add => AddHandler(ClickEvent, value);
- remove => RemoveHandler(ClickEvent, value);
- }
- public static readonly RoutedEvent MouseDoubleClickEvent =
- EventManager.RegisterRoutedEvent("MouseDoubleClick", RoutingStrategy.Bubble,
- typeof(RoutedEventHandler), typeof(NotifyIcon));
- public event RoutedEventHandler MouseDoubleClick
- {
- add => AddHandler(MouseDoubleClickEvent, value);
- remove => RemoveHandler(MouseDoubleClickEvent, value);
- }
- private void UpdateDataContext(FrameworkElement target, object oldValue, object newValue)
- {
- if (target == null || BindingOperations.GetBindingExpression(target, DataContextProperty) != null) return;
- if (ReferenceEquals(this, target.DataContext) || Equals(oldValue, target.DataContext))
- {
- target.DataContext = newValue ?? this;
- }
- }
- private void Dispose(bool disposing)
- {
- if (_isDisposed) return;
- if (disposing)
- {
- if (_dispatcherTimerBlink != null && IsBlink)
- {
- _dispatcherTimerBlink.Stop();
- }
- UpdateIcon(false);
- }
- _isDisposed = true;
- }
- }
|