如果您不熟悉 Ookii.Dialogs ,我建议您先look at this web page。它是开源,您可以在那里找到源代码,编译的二进制文档和文档示例应用程序。
在我的应用程序中,我正在使用 Ookii.Dialogs.Wpf.ProgressDialog 到 ShowDialog(this)一个进程对话框,对文件进行一些处理(这个始终是应用程序的主窗口)。正如预期的那样,进度对话框在实际可见之前大约需要一秒钟(即使它已经在处理我的文件)。
在进度对话框的 DoWork 线程中,我还检查输出文件是否已存在,并询问用户是否覆盖每个文件或跳过输出。我使用 Ookii.Dialogs.Wpf.TaskDialog 到 ShowDialog(this) “带命令链接的任务对话框”(看起来像{{3} })并询问用户覆盖问题 - 除非操作系统不支持它,我回到常规 MessageBox (该问题同样适用于消息框)。
当我的应用程序在进度对话框的 DoWork 线程的开头找到现有文件时,会出现问题。当出现任务对话框询问用户是否覆盖:
预期行为:任务对话框必须保持最佳状态。当出现进度对话框时(延迟1秒后),它必须出现在任务对话框后面。
实际行为:任务对话框不会保持最佳状态。当1s延迟后出现进度对话框时,它出现在任务对话框的顶部。
当进度对话框已经可见时,后续覆盖请求中不会发生实际行为。尽管用户可以在两个对话框之间来回切换(只是无法从其中任何一个切换到主窗口),任务对话框会在后续对话框的进度对话框中正确显示。
我正在寻找:
我不正在寻找以下内容:
答案 0 :(得分:1)
我知道这可能会有点迟到,但我只是在我自己的程序中抢先一个类似的问题,它让我想起了这个问题。 我使用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
我不是很擅长评论我的代码或理解我的解释所以如果您对正在发生的事情有任何疑问,我会尽力帮助。
答案 1 :(得分:0)
今天我已经阅读了这个问题并为我找到了解决方案。尝试使用TaskDialog,这是有效的。没试过其他对话框。 我写了一个DialogControler来处理MVVM。 这个DialogControlar有一个名为'Owner'的属性,它包含WPF-MainWindow。 然后我用它来调用(在我的情况下,我来自viewmodel中的backgroundthread)并在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)));
}
有了这个,我得到了一个最顶层的窗口。