mirror of
https://github.com/ckaczor/wpf-notifyicon.git
synced 2026-02-02 09:45:36 -05:00
WPF NotifyIcon
-------------- CHG Remove PlacementTarget assignment for popups and others. Did not provide advantages, but hid popups if taskbar owner isn't visible. ADD Added double click command declaration. git-svn-id: https://svn.evolvesoftware.ch/repos/evolve.net/WPF/NotifyIcon@83 9f600761-6f11-4665-b6dc-0185e9171623
This commit is contained in:
@@ -4,6 +4,7 @@ using System.Drawing;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Controls.Primitives;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using Hardcodet.Wpf.TaskbarNotification.Interop;
|
||||
|
||||
@@ -207,7 +208,7 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
{
|
||||
ImageSource newValue = (ImageSource)e.NewValue;
|
||||
|
||||
//resolving the ImageSource at design time probably won't work
|
||||
//resolving the ImageSource at design time is unlikely to work
|
||||
if (!Util.IsDesignMode) Icon = newValue.ToIcon();
|
||||
}
|
||||
|
||||
@@ -550,6 +551,169 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
#endregion
|
||||
|
||||
#region DataContext dependency property override
|
||||
|
||||
/// <summary>
|
||||
/// A static callback listener which is being invoked if the
|
||||
/// <see cref="FrameworkElement.DataContextProperty"/> dependency property has
|
||||
/// been changed. Invokes the <see cref="OnDataContextPropertyChanged"/>
|
||||
/// instance method of the changed instance.
|
||||
/// </summary>
|
||||
/// <param name="d">The currently processed owner of the property.</param>
|
||||
/// <param name="e">Provides information about the updated property.</param>
|
||||
private static void DataContextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
TaskbarIcon owner = (TaskbarIcon) d;
|
||||
owner.OnDataContextPropertyChanged(e);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Handles changes of the <see cref="FrameworkElement.DataContextProperty"/> dependency property. As
|
||||
/// WPF internally uses the dependency property system and bypasses the
|
||||
/// <see cref="FrameworkElement.DataContext"/> property wrapper, updates of the property's value
|
||||
/// should be handled here.
|
||||
/// </summary
|
||||
/// <param name="e">Provides information about the updated property.</param>
|
||||
private void OnDataContextPropertyChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
object newValue = e.NewValue;
|
||||
object oldValue = e.OldValue;
|
||||
|
||||
//replace custom data context for popup and tooltip, if
|
||||
//they are reflecting the data context's data context
|
||||
var popup = TrayPopupResolved;
|
||||
var toolTip = TrayToolTipResolved;
|
||||
|
||||
if (popup != null && Equals(popup.DataContext, oldValue))
|
||||
{
|
||||
popup.DataContext = newValue;
|
||||
}
|
||||
|
||||
if (toolTip != null && Equals(toolTip.DataContext, oldValue))
|
||||
{
|
||||
toolTip.DataContext = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
|
||||
#region DoubleClickCommand dependency property
|
||||
|
||||
/// <summary>
|
||||
/// Associates a command that is being executed if the tray icon is being
|
||||
/// double clicked.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DoubleClickCommandProperty =
|
||||
DependencyProperty.Register("DoubleClickCommand",
|
||||
typeof (ICommand),
|
||||
typeof (TaskbarIcon),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// A property wrapper for the <see cref="DoubleClickCommandProperty"/>
|
||||
/// dependency property:<br/>
|
||||
/// Associates a command that is being executed if the tray icon is being
|
||||
/// double clicked.
|
||||
/// </summary>
|
||||
public ICommand DoubleClickCommand
|
||||
{
|
||||
get { return (ICommand) GetValue(DoubleClickCommandProperty); }
|
||||
set { SetValue(DoubleClickCommandProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DoubleClickCommandParameter dependency property
|
||||
|
||||
/// <summary>
|
||||
/// Command parameter for the <see cref="DoubleClickCommand"/>.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DoubleClickCommandParameterProperty =
|
||||
DependencyProperty.Register("DoubleClickCommandParameter",
|
||||
typeof (object),
|
||||
typeof (TaskbarIcon),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// A property wrapper for the <see cref="DoubleClickCommandParameterProperty"/>
|
||||
/// dependency property:<br/>
|
||||
/// Command parameter for the <see cref="DoubleClickCommand"/>.
|
||||
/// </summary>
|
||||
public object DoubleClickCommandParameter
|
||||
{
|
||||
get { return GetValue(DoubleClickCommandParameterProperty); }
|
||||
set { SetValue(DoubleClickCommandParameterProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LeftClickCommand dependency property
|
||||
|
||||
/// <summary>
|
||||
/// Associates a command that is being executed if the tray icon is being
|
||||
/// double clicked.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty LeftClickCommandProperty =
|
||||
DependencyProperty.Register("LeftClickCommand",
|
||||
typeof (ICommand),
|
||||
typeof (TaskbarIcon),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// A property wrapper for the <see cref="LeftClickCommandProperty"/>
|
||||
/// dependency property:<br/>
|
||||
/// Associates a command that is being executed if the tray icon is being
|
||||
/// double clicked.
|
||||
/// </summary>
|
||||
public ICommand LeftClickCommand
|
||||
{
|
||||
get { return (ICommand) GetValue(LeftClickCommandProperty); }
|
||||
set { SetValue(LeftClickCommandProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region LeftClickCommandParameter dependency property
|
||||
|
||||
/// <summary>
|
||||
/// Command parameter for the <see cref="LeftClickCommand"/>.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty LeftClickCommandParameterProperty =
|
||||
DependencyProperty.Register("LeftClickCommandParameter",
|
||||
typeof (object),
|
||||
typeof (TaskbarIcon),
|
||||
new FrameworkPropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// A property wrapper for the <see cref="LeftClickCommandParameterProperty"/>
|
||||
/// dependency property:<br/>
|
||||
/// Command parameter for the <see cref="LeftClickCommand"/>.
|
||||
/// </summary>
|
||||
public object LeftClickCommandParameter
|
||||
{
|
||||
get { return GetValue(LeftClickCommandParameterProperty); }
|
||||
set { SetValue(LeftClickCommandParameterProperty, value); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Executes a given command.
|
||||
/// </summary>
|
||||
/// <param name="command">The command to be executed.</param>
|
||||
/// <param name="commandParameter">An optional parameter that was associated with
|
||||
/// the command.</param>
|
||||
private static void RunCommand(ICommand command, object commandParameter)
|
||||
{
|
||||
if (command == null) return;
|
||||
if (command.CanExecute(commandParameter))
|
||||
{
|
||||
command.Execute(commandParameter);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//EVENTS
|
||||
|
||||
@@ -576,7 +740,10 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
/// </summary>
|
||||
protected RoutedEventArgs RaiseTrayLeftMouseDownEvent()
|
||||
{
|
||||
return RaiseTrayLeftMouseDownEvent(this);
|
||||
//first raise event, then command
|
||||
RoutedEventArgs args = RaiseTrayLeftMouseDownEvent(this);
|
||||
RunCommand(LeftClickCommand, LeftClickCommandParameter);
|
||||
return args;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -824,7 +991,9 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
/// </summary>
|
||||
protected RoutedEventArgs RaiseTrayMouseDoubleClickEvent()
|
||||
{
|
||||
return RaiseTrayMouseDoubleClickEvent(this);
|
||||
RoutedEventArgs args = RaiseTrayMouseDoubleClickEvent(this);
|
||||
RunCommand(DoubleClickCommand, DoubleClickCommandParameter);
|
||||
return args;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -1515,6 +1684,11 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
//register change listener for the Visibility property
|
||||
PropertyMetadata md = new PropertyMetadata(Visibility.Visible, VisibilityPropertyChanged);
|
||||
VisibilityProperty.OverrideMetadata(typeof(TaskbarIcon), md);
|
||||
|
||||
//register change listener for the DataContext property
|
||||
md = new FrameworkPropertyMetadata(new PropertyChangedCallback(DataContextPropertyChanged));
|
||||
DataContextProperty.OverrideMetadata(typeof(TaskbarIcon), md);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -149,17 +149,24 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
CloseBalloon();
|
||||
}
|
||||
|
||||
|
||||
//create an invisible popup that hosts the UIElement
|
||||
Popup popup = new Popup();
|
||||
popup.AllowsTransparency = true;
|
||||
|
||||
//provide the popup with the taskbar icon's data context
|
||||
popup.DataContext = DataContext;
|
||||
|
||||
//don't animate by default - devs can use attached
|
||||
//events or override
|
||||
popup.PopupAnimation = animation;
|
||||
|
||||
Popup.CreateRootPopup(popup, balloon);
|
||||
|
||||
popup.PlacementTarget = this;
|
||||
//TODO we don't really need this and it causes the popup to become hidden if the
|
||||
//TaskbarIcon's parent is hidden, too...
|
||||
//popup.PlacementTarget = this;
|
||||
|
||||
popup.Placement = PlacementMode.AbsolutePoint;
|
||||
popup.StaysOpen = true;
|
||||
|
||||
@@ -332,10 +339,9 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
if (visible)
|
||||
{
|
||||
if (ContextMenu != null && ContextMenu.IsOpen ||
|
||||
TrayPopupResolved != null && TrayPopupResolved.IsOpen)
|
||||
if (IsPopupOpen)
|
||||
{
|
||||
//ignore if we have an open context menu or popup
|
||||
//ignore if we are already displaying something down there
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -389,7 +395,10 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
//create an invisible tooltip that hosts the UIElement
|
||||
tt = new ToolTip();
|
||||
tt.Placement = PlacementMode.Mouse;
|
||||
tt.PlacementTarget = this;
|
||||
|
||||
//TODO we don't really need this and it causes the popup to become hidden if the
|
||||
//TaskbarIcon's parent is hidden, too.
|
||||
//tt.PlacementTarget = this;
|
||||
|
||||
//the tooltip (and implicitly its context) explicitly gets
|
||||
//the DataContext of this instance. If there is no DataContext,
|
||||
@@ -484,7 +493,10 @@ namespace Hardcodet.Wpf.TaskbarNotification
|
||||
|
||||
Popup.CreateRootPopup(popup, TrayPopup);
|
||||
|
||||
popup.PlacementTarget = this;
|
||||
//TODO we don't really need this and it causes the popup to become hidden if the
|
||||
//TaskbarIcon's parent is hidden, too.
|
||||
//popup.PlacementTarget = this;
|
||||
|
||||
popup.Placement = PlacementMode.AbsolutePoint;
|
||||
popup.StaysOpen = false;
|
||||
}
|
||||
|
||||
@@ -72,6 +72,7 @@
|
||||
Language="de-ch" /></TextBlock>
|
||||
<Button
|
||||
Click="OnButtonClick"
|
||||
ToolTip="{Binding Path=ToolTipText}"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Bottom"
|
||||
Width="89"
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
mc:Ignorable="d"
|
||||
xmlns:local="clr-namespace:Sample_Project" MinWidth="750" MinHeight="800">
|
||||
xmlns:local="clr-namespace:Sample_Project"
|
||||
xmlns:Commands="clr-namespace:Sample_Project.Commands" MinWidth="750" MinHeight="800">
|
||||
<Window.Resources>
|
||||
|
||||
<BooleanToVisibilityConverter
|
||||
@@ -63,7 +64,9 @@
|
||||
ToolTipText="{Binding Path=Text, ElementName=txtToolTipText, Mode=Default}"
|
||||
Visibility="{Binding Path=IsChecked, Converter={StaticResource BooleanToVisibilityConverter}, ElementName=iconVisibility, Mode=Default}"
|
||||
MenuActivation="{Binding Path=SelectedItem, ElementName=lstMenuTrigger, Mode=Default}"
|
||||
PopupActivation="{Binding Path=SelectedItem, ElementName=lstPopupTrigger, Mode=Default}">
|
||||
PopupActivation="{Binding Path=SelectedItem, ElementName=lstPopupTrigger, Mode=Default}"
|
||||
DoubleClickCommand="{Binding Source={x:Static Commands:TaskbarIconCommands.ShowMain}}"
|
||||
>
|
||||
|
||||
<tb:TaskbarIcon.TrayPopup>
|
||||
<!-- the control will be put into a popup with an explicit DataContext -->
|
||||
@@ -141,10 +144,11 @@
|
||||
Margin="125,0,17,133"
|
||||
x:Name="txtBalloonTitle"
|
||||
VerticalAlignment="Bottom"
|
||||
Height="23" />
|
||||
Height="23">WPF NotifyIcon</TextBox>
|
||||
<TextBox
|
||||
Margin="125,0,17,76"
|
||||
x:Name="txtBalloonText" AcceptsReturn="True" Height="47" VerticalAlignment="Bottom" d:LayoutOverrides="VerticalAlignment" />
|
||||
x:Name="txtBalloonText" AcceptsReturn="True" Height="47" VerticalAlignment="Bottom" d:LayoutOverrides="VerticalAlignment"
|
||||
TextWrapping="Wrap">You should see a grey LED icon in your system tray. This is your NotifyIcon</TextBox>
|
||||
<RadioButton
|
||||
HorizontalAlignment="Left"
|
||||
Margin="14,0,0,54"
|
||||
@@ -377,7 +381,7 @@
|
||||
<Border HorizontalAlignment="Stretch" Width="Auto" BorderThickness="2,2,2,2" BorderBrush="#FF000000"/>
|
||||
<Button Content="Display Message" x:Name="showCustomBalloon"
|
||||
Click="showCustomBalloon_Click" HorizontalAlignment="Right" Margin="0,0,24.377,10.52" Width="107.623" Height="23" VerticalAlignment="Bottom" />
|
||||
<TextBox VerticalAlignment="Bottom" Height="23" Text="Balloon Title" TextWrapping="Wrap" Margin="10,0,173,10" x:Name="customBalloonTitle"/>
|
||||
<TextBox VerticalAlignment="Bottom" Height="23" Text="WPF Balloon" TextWrapping="Wrap" Margin="10,0,173,10" x:Name="customBalloonTitle"/>
|
||||
<TextBlock Margin="10,10,24.377,0" VerticalAlignment="Top" TextWrapping="Wrap"><Run Text="Custom Balloon Tips are more flexible then standard tips when it comes to styling..." Language="de-ch"/></TextBlock>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -12,6 +12,13 @@ namespace Sample_Project
|
||||
public Window1()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
|
||||
Loaded += delegate
|
||||
{
|
||||
//show balloon at startup, pointing to the icon
|
||||
showBalloonTip_Click(null, null);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user