Skip to content
36 changes: 32 additions & 4 deletions src/Wpf.Ui.Tray/Controls/NotifyIcon.cs
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,9 @@ public NotifyIcon()
internalNotifyIconManager = new Wpf.Ui.Tray.Internal.InternalNotifyIconManager();

RegisterHandlers();

// Listen for DataContext changes to update ContextMenu
DataContextChanged += OnDataContextChanged;
}

/// <summary>
Expand Down Expand Up @@ -363,6 +366,9 @@ protected virtual void Dispose(bool disposing)

System.Diagnostics.Debug.WriteLine($"INFO | {typeof(NotifyIcon)} disposed.", "Wpf.Ui.NotifyIcon");

// Clean up event handlers
DataContextChanged -= OnDataContextChanged;

Unregister();

internalNotifyIconManager.Dispose();
Expand All @@ -375,6 +381,13 @@ protected virtual void Dispose(bool disposing)
protected virtual void OnMenuChanged(ContextMenu contextMenu)
{
internalNotifyIconManager.ContextMenu = contextMenu;

// Set the DataContext for ContextMenu to enable binding
if (contextMenu.DataContext == null && DataContext != null)
{
contextMenu.DataContext = DataContext;
}

internalNotifyIconManager.ContextMenu.SetCurrentValue(Control.FontSizeProperty, MenuFontSize);
}

Expand Down Expand Up @@ -410,11 +423,11 @@ private static void OnFocusOnLeftClickChanged(DependencyObject d, DependencyProp
if (e.NewValue is not bool newValue)
{
notifyIcon.FocusOnLeftClick = false;

notifyIcon.internalNotifyIconManager.FocusOnLeftClick = false;
return;
}

notifyIcon.FocusOnLeftClick = newValue;
notifyIcon.internalNotifyIconManager.FocusOnLeftClick = newValue;
}

private static void OnMenuOnRightClickChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
Expand All @@ -427,11 +440,11 @@ private static void OnMenuOnRightClickChanged(DependencyObject d, DependencyProp
if (e.NewValue is not bool newValue)
{
notifyIcon.MenuOnRightClick = false;

notifyIcon.internalNotifyIconManager.MenuOnRightClick = false;
return;
}

notifyIcon.MenuOnRightClick = newValue;
notifyIcon.internalNotifyIconManager.MenuOnRightClick = newValue;
}

private static void OnMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
Expand All @@ -455,6 +468,12 @@ private void InitializeIcon()
internalNotifyIconManager.Icon = Icon;
internalNotifyIconManager.MenuOnRightClick = MenuOnRightClick;
internalNotifyIconManager.FocusOnLeftClick = FocusOnLeftClick;

// Add Menu initialization
if (Menu != null)
{
OnMenuChanged(Menu);
}
}

private void RegisterHandlers()
Expand All @@ -466,4 +485,13 @@ private void RegisterHandlers()
internalNotifyIconManager.MiddleClick += OnMiddleClick;
internalNotifyIconManager.MiddleDoubleClick += OnMiddleDoubleClick;
}

private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
// Update ContextMenu DataContext when NotifyIcon DataContext changes
if (Menu != null && e.NewValue != null)
{
Menu.DataContext = e.NewValue;
}
}
}
5 changes: 4 additions & 1 deletion src/Wpf.Ui.Tray/Internal/InternalNotifyIconManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,10 @@ protected virtual void OpenMenu()

// Without setting the handler window at the front, menu may appear behind the taskbar
_ = Interop.User32.SetForegroundWindow(HookWindow.Handle);
ContextMenuService.SetPlacement(ContextMenu, PlacementMode.MousePoint);

// Set placement properties for better positioning
ContextMenu.SetCurrentValue(ContextMenu.PlacementProperty, PlacementMode.MousePoint);
ContextMenu.SetCurrentValue(ContextMenu.PlacementTargetProperty, null);

// ContextMenu.ApplyMica();
ContextMenu.SetCurrentValue(ContextMenu.IsOpenProperty, true);
Expand Down