How do I center the OpenFileDialog to its parent Window in WPF?
I'm using WPF's OpenFileDialog, and I'm looking for a way to make sure it is centered in the parent window when shown. It seems to be missing obvious properties like StartupPosition that might enable this.
Does anybody know the secret?
Update: It seems that the first 开发者_StackOverflowtime I open it, it does appear in the center of the parent, but if I move it, it then remembers its position, and doesn't open centered on subsequent occassions.
here is the code of a generic class that allows to play with "sub dialogs" like this one:
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;
}
}
And this is how you would use it in a standard WPF app. Here I just copy the parent window size, but I'll let you do the center math :-)
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);
}
CommonDialog in WPF does not inherit from window class, so it does not have StartupPosition property.
Check this blog post for one solution: OpenFileDialog in .NET on Vista
In short, it wraps dialog in a window and then shows it.
精彩评论