Заставить событие щелчка NotifyIcon вести себя так же, как значок на панели задач - PullRequest
0 голосов
/ 26 марта 2019

Я пишу программу на C # с использованием WPF с шаблоном MVVM и Caliburn Micro. Я не хочу, чтобы у моего приложения был значок на панели задач, я просто хочу, чтобы он находился в системном трее. Я добился этого с помощью NotifyIcon, но проблема в том, что я не могу заставить значок уведомления вести себя при нажатии так же, как значок на панели задач.

Если вы посмотрите на значок на панели задач, щелкните поведение:

  1. Если окно в данный момент активно, щелчок делает его свернутым.
  2. Если окно потеряло фокус или закрыто другим окном, щелчок делает его видимым и имеет фокус.
  3. Если окно свернуто, клик делает его видимым и имеет фокус.

Я пытался достичь этого разными способами, но ни один из них не был успешным.

Теперь у меня есть событие щелчка, прикрепленное к методу ShowHide, пользовательское свойство ChangeActivation, которое позволяет мне активировать окно при отображении, а не когда пользователь щелкает за пределами окна, запускается событие Деактивировано.

Окно:

<Window cal:Message.Attach="[Event Deactivated] = [Action WindowDeactivated]">

NotifyIcon:

<tb:TaskbarIcon IconSource="{StaticResource Icon}" cal:Message.Attach="[Event TrayLeftMouseDown] = [Action ShowHide]">
        <tb:TaskbarIcon.ContextMenu>
            <ContextMenu>
                <MenuItem Header="Zamknij" cal:Message.Attach="[Event Click] = [Action Close]"/>
            </ContextMenu>
        </tb:TaskbarIcon.ContextMenu>
</tb:TaskbarIcon>

Код модели:

    public void ShowHide()
    {
        if (WindowState == Dictionary.State_MINIMIZED)
        {
            Show();
        }
        else
        {
            Hide();
        }
    }

    //Used to minimize window if got covered by the other.
    public void WindowDeactivated()
    {
        ShowHide();
    }

    private void Show()
    {

            WindowState = Dictionary.State_NORMAL;
            IsTopmost = true;
            IsTopmost = false;
            ChangeActivated = true;

    }

    private void Hide()
    {

            //IsTaskbarVisible is a workaround to prevent showing minimized window in left bottom corner of the screen
            IsTaskbarVisible = true;
            WindowState = Dictionary.State_MINIMIZED;
            IsTaskbarVisible = false;
            ChangeActivated = false;

    }

Код окна:

    public static readonly DependencyProperty ActivatedProperty =
    DependencyProperty.Register(
    "ChangeActivated",
    typeof(Boolean),
    typeof(CustomWindow),
    new PropertyMetadata(OnActivatedChanged));

    public Boolean ChangeActivated
    {
        get { return (Boolean)GetValue(ActivatedProperty); }
        set { SetValue(ActivatedProperty, value); }
    }

    static void OnActivatedChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        var d = (CustomWindow)dependencyObject;
        if (d.ChangeActivated)
        {
            d.Activate();
        }
    }

Проблема в том, что это решение работает, когда пользователь отображает окно, щелкая значок, и скрывает его, щелкая другое окно. Если пользователь нажимает на значок, а затем снова нажимает, чтобы скрыть окно, оно исчезает и снова отображается, потому что деактивированное событие вызывается в результате нажатия на значок (который находится вне окна), а затем вызывается ShowHide из-за выполнения щелчка мыши.

Есть ли решение, которое позволит мне добиться поведения значка на панели задач Windows?

...