Как восстановить свернутое / скрытое окно? - PullRequest
1 голос
/ 03 августа 2020

У меня есть Материал Windows из MaterialDesignInXaml, который можно свернуть в панели уведомлений.

Я скрываю windows, устанавливая Visibility на Collapsed.

двойной щелчок по значку запускает команду для восстановления 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 изменил видимость в нем и уведомит об изменении OnPropertyChanded.

windows отображается на панели задач, но не появляется на переднем плане моего экрана.

Как вы можете видеть в комментарии, я пробовал разные способы получить его безуспешно, например:

  • Focusable свойство
  • TopMost свойство
  • Top свойство
  • Даже поведение для активации windows

Есть ли что-то особенное, чтобы поместить windows на передний план экрана?

Отредактируйте, чтобы добавить образец репо:

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>

Main Windows конструктор устанавливает для контекста данных новую MainViewModel.

MainViewModel.cs: (ViewModelBase - это класс ssi c один со свойством 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
}

И, наконец, мой 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;
   }
}

Для пакетов я установил Hardcodet.NotifyIcon.Wpf, MaterialDesignExtensionss 3.1. 0 (и зависимости materialDesign) и System. Windows .Interactivity.WPF.

1 Ответ

1 голос
/ 03 августа 2020

Измените свой ExecuteOpenWindowsCommand, чтобы установить только свойство Activated.

private void ExecuteOpenWindowsCommand()
{
   Activated = true;
}

Адаптируйте метод OnActivatedChanged в ActivateBehavior следующим образом.

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();
}

Существенной частью является восстановление окна, чего раньше не было, оно было скрыто. Затем его нужно активировать, чтобы он вышел на передний план. Назначение состояния окна не требуется, но делает переход восстановления окна более приятным.

...