Почему TopMost=True не всегда работает?

У меня есть простое приложение, которое маленькое и должно плавать поверх всех моих других окон. Через несколько часов я замечу, что его больше нет поверх всех других моих окон, и мне было интересно, знает ли кто-нибудь, почему это происходит.

За это время я открывал новые приложения (в основном продукты MS 2010), несколько раз блокировал/разблокировал свой компьютер, нажимал ярлык на рабочем столе и перемещал приложение по экрану (иногда между экранами, так как у меня два монитора).

Мне не удалось воспроизвести поведение по запросу, однако это происходит не реже одного раза в день. Когда он перестает оставаться наверху, он прячется, когда я нажимаю ярлык на рабочем столе, поэтому я думаю, что каким-то образом свойство TopMost получает значение false.

<Window AllowsTransparency="True" 
        WindowStyle="None"
        Topmost="True"
        SizeToContent="WidthAndHeight"
        MouseDown="Window_MouseDown"
        ShowInTaskbar="False"
        Background="Transparent" 
        SnapsToDevicePixels="True">

Приложение действительно простое... оно просто работает как виртуальные шахматные часы и позволяет мне отслеживать время, потраченное на обработку звонков в службу поддержки, по сравнению с фактической разработкой. Событие MouseDown просто запускает поведение перетаскивания приложения, поскольку для WindowStyle установлено значение None.

Я использую WindowsXP, и приложение было построено на .Net 4.0.


person Rachel    schedule 21.02.2011    source источник
comment
Удачно заставить это работать? У меня была такая же проблема, и я еще не нашел надежного решения.   -  person Joseph Gabriel    schedule 01.12.2011
comment
@joeg К сожалению, нет. Мое окно все еще периодически исчезает   -  person Rachel    schedule 01.12.2011
comment
В моем приложении я последовательно воспроизводю потерю Topmost. Во-первых, у меня есть WindowA, который является самым верхним. В другом окне WindowB я делаю следующее: (1) устанавливаю WindowB.Topmost = true, затем (2) вызываю MessageBox.Show, затем (3) снова устанавливаю WindowB.Topmost = false. После этого WindowA потеряет самый верхний статус. Это довольно неприятно.   -  person Grant Birchmeier    schedule 10.04.2012


Ответы (3)


Возможно, вы могли бы перехватить событие Deactivated и снова заставить окно вернуться наверх?

На самом деле это всего лишь предположение, но стоило бы выяснить, исправит ли это установка Topmost = False, а затем Topmost = True в нужное время.

person Tom    schedule 21.02.2011
comment
Спасибо, я попробую, но не буду знать наверняка, работает ли он, пока он снова не перестанет оставаться поверх других окон. На данный момент я добавил предупреждение MessageBox и сбросил Topmost = True, когда окно деактивируется, а Topmost = False. - person Rachel; 21.02.2011
comment
До сих пор не удалось воспроизвести проблему ... не знаю, почему, так как это происходило ежедневно, прежде чем я опубликовал это. Ваша идея хороша, и я принимаю ее как ответ. - person Rachel; 24.02.2011
comment
К сожалению, это не работает... Я наблюдаю за событием Deactivated и выбрасываю всплывающее окно, если TopMost = false и оно никогда не срабатывает. - person Rachel; 22.03.2011

Альтернативное решение

в вашем WPF MainWindow

namespace YourNameSpace
{  
     public partial class MainWindow : Window
     {
    public MainWindow()
    {
        InitializeComponent();
    }

    private delegate void MessageBoxDelegate(DelegatePara para);

    public void ShowAwMessageBox(DelegatePara para)
    {            
        this.Dispatcher.BeginInvoke(new MessageBoxDelegate(ShowMessageBox), para);
    }

    private void ShowMessageBox(DelegatePara para)
    {
        this.Topmost = true;
        int typ = para.count;
        string msg = para.Msg;
        switch (typ)
        {
            case 0:
                MessageBox.Show(this, msg, "Auswertung", MessageBoxButton.OK, MessageBoxImage.Information);
                break;
            case 1:
                MessageBox.Show(this, msg, "Auswertung", MessageBoxButton.OK, MessageBoxImage.Error);
                break;
            case 2:
                MessageBox.Show(this, msg, "Auswertung", MessageBoxButton.OK, MessageBoxImage.Question);
                break;
            default:
                MessageBox.Show(this, msg, "Auswertung", MessageBoxButton.OK, MessageBoxImage.Information);
                break;
        }
    }
}

 public class DelegatePara
 {
    public int count {get;set; }
    public string Msg {get;set; }
 }
}

Затем вы вызываете его с дескриптором MainWind из любого места, даже в потоке.

this.MyWind.ShowRlvAwMessageBox(new DelegatePara() { count = 0, Msg = "Hallo World!" });
person jansen208    schedule 06.09.2012

Этот вопрос довольно старый, но я еще не нашел реальных решений, поэтому вот моя идея для всех, кто сталкивается с проблемой:

Попробуйте совет Тома, но вместо того, чтобы просто проверить, становится ли TopMost, используйте ShowWindowAsync, чтобы заставить его снова отображаться.

Единственное, что может быть проблемой, так это то, что он может сместить фокус с активного приложения, но я знаю, что есть способ сделать его формой «без фокуса», если это вариант для вас.

Собираюсь попробовать это для себя, поэтому я обновлю этот ответ, если он будет работать с деталями.

person BVernon    schedule 17.03.2014
comment
Собираюсь попробовать это для себя, поэтому я обновлю этот ответ, если он будет работать с деталями. - значит, не получилось? - person dontbyteme; 09.12.2016
comment
@dontbyteme О боже... извините, я забыл вернуться и обновить это. Не могу сказать, что сейчас точно помню, но не думаю, что это стало моим окончательным решением. Я думаю, что мне пришлось включить ответ на этот вопрос: stackoverflow.com/questions/156046/ - person BVernon; 13.12.2016
comment
@dontbyteme Хотя теперь, когда я снова смотрю, может быть, вы не хотите делать окно без фокуса, так что этот ответ может не помочь. Если ничего не помогает, просто установите таймер, чтобы вернуть его на первое место. Конечно, вы хотите убедиться, что когда вы это делаете, это не крадет фокус того, над чем вы работаете (или быстро возвращает его), так что это может быть еще одной проблемой само по себе. Надеюсь, то, что я сказал, поможет, и удачи! - person BVernon; 13.12.2016