Reputation: 175
I have MaterialWindows from MaterialDesignInXaml which can be minimized in the notification bar.
I hide the windows by setting the Visibility
to Collapsed
.
The double click on the icon launches a command to restore the windows:
public RelayCommand OpenWindowsCommand => new RelayCommand(ExecuteOpenWindowsCommand);
private void ExecuteOpenWindowsCommand(object o)
{
WindowState = WindowState.Normal;
//Activated = true;
//IsInForeground = true;
//IsInForeground = false;
//IsFocus = true;
}
My property WindowState
changed the visibility in it and notify the change with OnPropertyChanded
.
The windows appear in the task bar but doesn't come on the foreground of my screen.
As you can see in comment, I tried different ways to get it without success like :
Focusable
propertyTopMost
propertyTop
propertyIs there something special to put a windows in the foreground of the screen?
Edit to add a sample repo :
MainWindow.xaml
<controls:MaterialWindow
x:Class="MinimiedWindows.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Behaviors="clr-namespace:MinimiedWindows.Behavior"
xmlns:controls="clr-namespace:MaterialDesignExtensions.Controls;assembly=MaterialDesignExtensions"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:MinimiedWindows"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tb="http://www.hardcodet.net/taskbar"
Title="MainWindow"
Width="800"
Height="450"
Focusable="{Binding IsFocus}"
Icon="app.ico"
Topmost="{Binding IsFocus}"
Visibility="{Binding WindowsVisibility, Mode=TwoWay}"
WindowState="{Binding WindowState}"
mc:Ignorable="d">
<i:Interaction.Behaviors>
<Behaviors:ActivateBehavior Activated="{Binding Activated, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<Grid>
<tb:TaskbarIcon
x:Name="myNotifyIcon"
DoubleClickCommand="{Binding OpenWindowsCommand}"
IconSource="{Binding NotifyIcon}"
MenuActivation="LeftOrRightClick"
PopupActivation="DoubleClick"
ToolTip="aa"
Visibility="{Binding NotifyIconVisibility}" />
</Grid>
</controls:MaterialWindow>
MainWindows constructor set the datacontext to a new MainViewModel.
MainViewModel.cs : (ViewModelBase is the classic one with the property OnPropertyChanged)
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
}
#region Windows properties
private WindowState _WindowState = WindowState.Normal;
public WindowState WindowState
{
get { return _WindowState; }
set
{
_WindowState = value;
OnPropertyChanged();
OnPropertyChanged("WindowsVisibility");
OnPropertyChanged("NotifyIconVisibility");
}
}
private Visibility _WindowsVisibility = Visibility.Visible;
public Visibility WindowsVisibility
{
get
{
if (WindowState == WindowState.Minimized)
{
return Visibility.Collapsed;
}
return Visibility.Visible;
}
set { _WindowsVisibility = value; }
}
private bool _Activated;
public bool Activated
{
get { return _Activated; }
set
{
_Activated = value;
OnPropertyChanged();
}
}
private bool _IsInForeground;
public bool IsInForeground
{
get { return _IsInForeground; }
set
{
_IsInForeground = value;
OnPropertyChanged();
}
}
private bool _IsFocus;
public bool IsFocus
{
get { return _IsFocus; }
set
{
_IsFocus = value;
OnPropertyChanged();
}
}
#endregion
#region NotifyBar
public string NotifyIcon
{
get { return "app.ico"; }
}
public Visibility NotifyIconVisibility
{
get
{
if (WindowState == WindowState.Minimized)
{
return Visibility.Visible;
}
return Visibility.Collapsed;
}
}
public RelayCommand OpenWindowsCommand => new RelayCommand(ExecuteOpenWindowsCommand);
private void ExecuteOpenWindowsCommand(object o)
{
WindowState = WindowState.Normal;
Activated = true;
}
#endregion
}
And finally my ActivateBehavior.cs
public class ActivateBehavior : Behavior<MaterialWindow>
{
Boolean isActivated;
public static readonly DependencyProperty ActivatedProperty =
DependencyProperty.Register(
"Activated",
typeof(Boolean),
typeof(ActivateBehavior),
new PropertyMetadata(OnActivatedChanged)
);
public Boolean Activated
{
get { return (Boolean)GetValue(ActivatedProperty); }
set { SetValue(ActivatedProperty, value); }
}
static void OnActivatedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var behavior = (ActivateBehavior)dependencyObject;
if (!behavior.Activated || behavior.isActivated)
return;
// The Activated property is set to true but the Activated event (tracked by the
// isActivated field) hasn't been fired. Go ahead and activate the window.
if (behavior.AssociatedObject.WindowState == WindowState.Minimized)
behavior.AssociatedObject.WindowState = WindowState.Normal;
behavior.AssociatedObject.Activate();
}
protected override void OnAttached()
{
AssociatedObject.Activated += OnActivated;
AssociatedObject.Deactivated += OnDeactivated;
}
protected override void OnDetaching()
{
AssociatedObject.Activated -= OnActivated;
AssociatedObject.Deactivated -= OnDeactivated;
}
void OnActivated(Object sender, EventArgs eventArgs)
{
this.isActivated = true;
Activated = true;
}
void OnDeactivated(Object sender, EventArgs eventArgs)
{
this.isActivated = false;
Activated = false;
}
}
For the packages, I have installed Hardcodet.NotifyIcon.Wpf, MaterialDesignExtensionss 3.1.0 (and the materialDesign dependencies) and System.Windows.Interactivity.WPF.
Upvotes: 0
Views: 1022
Reputation: 22119
Change your ExecuteOpenWindowsCommand
to only set the Activated
property.
private void ExecuteOpenWindowsCommand()
{
Activated = true;
}
Adapt the OnActivatedChanged
method in the ActivateBehavior
like this.
private static void OnActivatedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
{
var behavior = (ActivateBehavior)dependencyObject;
if (!behavior.Activated || behavior.isActivated)
return;
// The Activated property is set to true but the Activated event (tracked by the
// isActivated field) hasn't been fired. Go ahead and activate the window.
var window = behavior.AssociatedObject;
if (window.WindowState == WindowState.Minimized)
{
window.WindowState = WindowState.Normal;
SystemCommands.RestoreWindow(window);
}
window.Activate();
}
The essential part is restoring the window, which did not happen before, it was hidden. Then it needs to be activated to come to foreground. The window state asssignment is not needed, but makes the restore transition of the window more pleasant.
Upvotes: 1