Ookii.Dialogs - убедитесь, что над диалогом хода выполнения появляется другое диалоговое окно. - PullRequest
0 голосов
/ 07 марта 2012

Если вы не знакомы с Ookii.Dialogs , я предлагаю вам сначала взглянуть на эту веб-страницу .Это с открытым исходным кодом , и вы можете найти исходный код, скомпилированный двоичный файл, документацию и пример приложения для загрузки там.

В моем приложении я использую Ookii.Dialogs.Wpf.ProgressDialog to ShowDialog (this) диалоговое окно прогресса, выполняющее некоторую обработку файлов ( this всегда является основным окном приложения).Как и ожидалось, диалоговое окно прогресса занимает около секунды, прежде чем оно фактически становится видимым (даже если оно уже выполняет обработку моих файлов).

В потоке DoWork диалога прогресса,Я также проверяю, существуют ли выходные файлы, и спрашиваю пользователя, перезаписать ли каждый файл или пропустить вывод.Я использую Ookii.Dialogs.Wpf.TaskDialog до ShowDialog (this) a «Диалог задач с командными ссылками» (выглядит как this ) и задать пользователю вопрос о перезаписи - кроме случаев, когда ОС не поддерживает его, я возвращаюсь к обычному MessageBox ( проблема также относится к окну сообщений ).

Проблема возникает, когда мое приложение находит существующий файл в начале потока DoWork диалогового окна прогресса.Когда появляется диалоговое окно задачи, спрашивающее пользователя, следует ли перезаписать:

Ожидаемое поведение: Диалог задачи должен оставаться сверху.Когда появляется диалоговое окно хода выполнения (с задержкой в ​​1 с), оно должно появляться за диалоговым окном задач.

Фактическое поведение: Диалог задач не остается сверху.Когда диалоговое окно выполнения появляется с задержкой в ​​1 с), оно появляется в верхней части диалогового окна задачи.

Фактическое поведение не возникает в последующих запросах на перезапись, когда диалоговое окно выполнения уже отображается.Диалоговое окно задач правильно отображается в верхней части диалогового окна хода выполнения для последующих, хотя пользователь может переключаться между двумя диалоговыми окнами (просто не может переключиться на главное окно из любого из них).

IИщу это:

  • Лучшее решение: Сделать диалог задачи модальным в диалоге прогресса .Если пользователь пытается переключиться в диалоговое окно прогресса, ему нельзя разрешать это делать.
  • Второй лучший вариант: Сделать первое появление диалогового окна задач оставаться наверху, даже когда появляется диалоговое окно прогрессапосле задержки в 1 с.

Я не ищу следующее:

  • Установите флаг диалогового окна задачи всегда сверху.Я не хочу, чтобы диалоговое окно задач отображалось всегда поверх каждого окна на компьютере пользователя.
  • Добавьте задержку до появления диалогового окна задачи.Я пробовал Thread.Sleep () даже в цикле, он просто останавливает выполнение всего и не решает проблему.
  • Подождите, пока не появится диалоговое окно прогресса, прежде чем показывать задачудиалог.Может работать теоретически, за исключением того, что я не нашел способа узнать, появился диалог прогресса или нет.
  • Сделать диалоги немодальными.Я хочу, чтобы они оба были модальными.(Кроме того, я попытался сделать их немодальными; это не помогает решить проблему.)
  • Решение, которое работает только для диалога задач.Это должно работать и для обычного окна сообщения.

Ответы [ 2 ]

1 голос
/ 18 августа 2012

Я знаю, что это может произойти немного поздно, но я просто воспользовался аналогичной проблемой в моей собственной программе, и она напомнила мне об этом вопросе. Я использовал функцию Windows FindWindowEx API для свойства заголовка окна диалоговых окон задач, чтобы найти дескриптор окна диалогов, а затем использовал свой собственный класс, чтобы сделать его Iwin32Window, который затем можно использовать в качестве родительского для окна сообщения или диалога задач. соответствующий код ниже (VB.NET)

    'allows us to use the handle as a window
    class window
        Implements IWin32Window
        private _handle

        public sub new(handle as intptr)
            _handle = handle
        end sub

        Public ReadOnly Property Handle As System.IntPtr Implements System.Windows.Forms.IWin32Window.Handle
            Get
                Return _h
            End Get
        End Property
    end class

    'Declare the needed DLL import
    class NativeMethods
        <DllImport("user32.dll", SetLastError:=True, ThrowOnUnmappableChar:=True, CharSet:=CharSet.Unicode, bestFitMapping:=False)>
        Public Shared Function FindWindowEx(hwndParent As IntPtr, hwndChildAfter As IntPtr, lpszClass As String, lpszWindow As String) As IntPtr
        End Function
    end class

    'Make sure you've set a window title when you run your task
    sub runTask()
        dim myDlg as Ookii.Dialogs.ProgressDialog
        'Do what you need to here
        myDlg.WindowTitle = "make sure you set a title"
    end sub
    sub myTask(sender as object, e As System.ComponentModel.DoWorkEventArgs)
         'Checks and balances here
         if fileExists then
              'this is the dialog that's running our task
              Dim dlg As Ookii.Dialogs.ProgressDialog = DirectCast(sender, Ookii.Dialogs.ProgressDialog)
              'Find the window handle
              Dim dlgHandle As IntPtr = NativeMethods.FindWindowEx(IntPtr.Zero, IntPtr.Zero, Nothing, dlg.WindowTitle)
              'make it an Iwin32Window
              dim dlgWindow as new window(dlgHandle)
              'That can then be used as a parent for the message box or the task dialog
              MessageBox.Show(dlgWindow,"The file exists, overwrite?")
         end if
    end sub

Я не очень хорошо комментирую свой код или понимаю мои объяснения, поэтому, если у вас есть какие-либо вопросы о том, что происходит, я постараюсь помочь.

0 голосов
/ 23 июля 2014

Сегодня я прочитал вопрос и нашел решение для меня. Пробовал это для TaskDialog, и это не работает. Не пробовал с другими диалогами. Я написал DialogControler для работы с MVVM. Этот DialogControlar имеет свойство «Владелец», которое содержит WPF-MainWindow. Затем я использую это для вызова (в моем случае я пришел из backgroundthread в viewmodel), а также устанавливаю это в ShowDialog.

Мой код:

using (var dialog = new Ookii.Dialogs.Wpf.TaskDialog())
        {
            dialog.WindowTitle = "My title";
            dialog.MainInstruction = "My text";
            var okButton = new Ookii.Dialogs.Wpf.TaskDialogButton(Ookii.Dialogs.Wpf.ButtonType.Ok);
            dialog.Buttons.Add(okButton);
            Owner.Dispatcher.Invoke(new Action(() => dialog.ShowDialog(Owner)));

        }

С этим я получил самое верхнее окно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...