Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在WPF中将OpenFileDialog置于其父窗口的中心?_Wpf_Openfiledialog - Fatal编程技术网

如何在WPF中将OpenFileDialog置于其父窗口的中心?

如何在WPF中将OpenFileDialog置于其父窗口的中心?,wpf,openfiledialog,Wpf,Openfiledialog,我正在使用WPF,我正在寻找一种方法来确保它在显示时位于父窗口的中心。它似乎缺少了像StartupPosition这样可以实现这一点的明显属性 有人知道这个秘密吗 更新:似乎我第一次打开它时,它确实出现在父对象的中心,但如果我移动它,它会记住它的位置,并且不会在后续事件中以中心位置打开。WPF中的CommonDialog不会从window类继承,因此它没有StartupPosition属性 查看此博客文章,了解一种解决方案: 简而言之,它将对话框包装在窗口中,然后显示它 下面是一个通用类的代码,

我正在使用WPF,我正在寻找一种方法来确保它在显示时位于父窗口的中心。它似乎缺少了像StartupPosition这样可以实现这一点的明显属性

有人知道这个秘密吗


更新:似乎我第一次打开它时,它确实出现在父对象的中心,但如果我移动它,它会记住它的位置,并且不会在后续事件中以中心位置打开。

WPF中的CommonDialog不会从window类继承,因此它没有StartupPosition属性

查看此博客文章,了解一种解决方案:

简而言之,它将对话框包装在窗口中,然后显示它

下面是一个通用类的代码,该类允许使用如下“子对话框”:

public class SubDialogManager : IDisposable
{
    public SubDialogManager(Window window, Action<IntPtr> enterIdleAction)
        :this(new WindowInteropHelper(window).Handle, enterIdleAction)
    {
    }

    public SubDialogManager(IntPtr hwnd, Action<IntPtr> enterIdleAction)
    {
        if (enterIdleAction == null)
            throw new ArgumentNullException("enterIdleAction");

        EnterIdleAction = enterIdleAction;
        Source = HwndSource.FromHwnd(hwnd);
        Source.AddHook(WindowMessageHandler);
    }

    protected HwndSource Source { get; private set; }
    protected Action<IntPtr> EnterIdleAction { get; private set; }

    void IDisposable.Dispose()
    {
        if (Source != null)
        {
            Source.RemoveHook(WindowMessageHandler);
            Source = null;
        }
    }

    private const int WM_ENTERIDLE = 0x0121;

    protected virtual IntPtr WindowMessageHandler(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    {
        if (msg == WM_ENTERIDLE)
        {
            EnterIdleAction(lParam);
        }
        return IntPtr.Zero;
    }
}

这似乎是我进行快速测试时的默认行为。你能更详细地描述一下你的情况吗?@Fredrik-我在问题中添加了另一个细节,这是我第一次看到一个不被接受的问题,这个问题的OP不仅有50分,而且还有17.2k的巨大差距,真让你感到羞耻。:)我有一个后续问题要问你们。。谢谢你。您链接到的解决方案是有效地使用WinForms OpenFileDialog,我希望避免这种情况。我可能在这里遗漏了一些东西,但您似乎在更改父窗口,而不是使用OpenFileDialog执行任何操作?@Samuel-WM\u ENTERIDLE被发送到一个对话框(这里是OpenFileDialog)所有者,lParam参数包含对话框的句柄。你试过代码吗?还没有试过代码-只是想先理解一下。现在您已经解释了WM_ENTERIDLE的意义,这一切都是有意义的。谢谢
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, RoutedEventArgs e)
    {
        bool computed = false; // do this only once
        int x = (int)Left;
        int y = (int)Top;
        int w = (int)Width;
        int h = (int)Height;
        using (SubDialogManager center = new SubDialogManager(this, ptr => { if (!computed) { SetWindowPos(ptr, IntPtr.Zero, x, y, w, h, 0); computed= true; } }))
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.ShowDialog(this);
        }
    }

    [DllImport("user32.dll")]
    private static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, int flags);
}