質問

任意のカスタムダイアログ(フォーム)用のWinFormアプリケーションで私がそれを表示する前に、私はそのサイズと位置を設定することができます:

form.StartPosition = FormStartPosition.Manual;
form.DesktopBounds = MyWindowPosition;
複数のモニタを扱うときに

このことは特に重要です。あなたはセカンドモニタにドラッグしているアプリケーションからダイアログを開いたときに、このようなコードがないと、ダイアログがプライマリモニタに表示されます。これは、貧弱なユーザーエクスペリエンスを提供します。

(開始位置のプロパティを持っていない)標準の.NET OpenFileDialogとSaveFileDialogのための位置を設定する任意のフックがある場合、私は疑問に思ってます。

役に立ちましたか?

解決

私はあなたができる最善のは、あなたがオーバーロードを使用してくださいがあると思われます親として使用するShowDialogを受け入れIWin32Windowするの。この はそれが適切な場所を選択するに役立つかもしれません。最も一般ます:

using(var dlg = new OpenFileDialog()) {
    .... setup
    if(dlg.ShowDialog(this) == DialogResult.OK) {
        .... use
    }
}

他のヒント

CodeProjectの上この記事をチェックしてください。抜粋ます:

  

ここでは、ときに便利です.NET   NativeWindowのは、A、画像に入ってきます   NativeWindowのはどこの窓ラッパーです   それはによって送信されたメッセージを処理します   それに関連付けられたハンドル。それが作成されます   NativeWindowの仲間と   それに対処OpenFileWindow。これから   に送信された時点、すべてのメッセージ   OpenFileWindowはにリダイレクトされます   で私たち自身のWndProcメソッド   NativeWindowの代わりに、私たちはすることができます   キャンセル、変更、またはそれらを通過させます   通じています。

     

私たちのWndProcメソッドでは、メッセージを処理します   WM_WINDOWPOSCHANGING。オープンの場合   ダイアログが開いている、我々は変更されます   元の水平または垂直   StartLocationに依存サイズ   ユーザによって設定されました。それが増分します   ウィンドウのサイズを作成します。この   コントロールがあるときに一度だけ起こります   オープンします。

     

また、私たちはメッセージを処理します   WM_SHOWWINDOW。ここでは、すべてのコントロール   元OpenFileDialogの内側にあります   作成した、と私たちは、追加しようとしています   オープンファイルダイアログに私たちのコントロール。   これは、Win32のAPIを呼び出すことによって行われ   SetParent関数。このAPIを使用すると、変更することができます   親ウィンドウ。次に、基本的に   何それがないと、私たちのコントロールを添付してあります   の元OpenFileDialogへ   応じて、それが設定された場所、   StartLocationプロパティの値ます。

     

これの利点は、我々はまだです   完全に制御を持っています   コントロールに添付   OpenFileDialogウィンドウ。これは、私たちを意味します   、イベントを受け取るメソッドを呼び出すと、することができます   私たちはそれらとやりたいです   コントロールます。

私は昨日のほとんどのために、この問題を抱えていました。 BobBの答えは、ほとんどの(おかげBobBを)私を手伝ったものだった。

あなたも、ウィンドウを作成し、dialog.ShowDialog()メソッド呼び出しの前に、それを閉じプライベートメソッドを作るために、それはまだOpenFileDialogを中心に説明する限り行くことができます。

private void openFileDialogWindow()
{
    Window openFileDialogWindow = new Window();
    openFileDialogWindow.Left = this.Left;
    openFileDialogWindow.Top = this.Top;
    openFileDialogWindow.Width = 0;
    openFileDialogWindow.Height = 0;
    openFileDialogWindow.WindowStyle = WindowStyle.None;
    openFileDialogWindow.ResizeMode = ResizeMode.NoResize;
    openFileDialogWindow.WindowStartupLocation = WindowStartupLocation.CenterScreen;

    openFileDialogWindow.Show();
    openFileDialogWindow.Close();

    openFileDialogWindow = null;
}

次にShowDialog()メソッドの前にいずれかの方法でそれを呼び出します。

public string SelectWebFolder()
{
    string WebFoldersDestPath = null;

    CommonOpenFileDialog filePickerDialog = new CommonOpenFileDialog();
    // OpenFileDialog Parameters..

    openFileDialogWindow();

    if (filePickerDialog.ShowDialog() == CommonFileDialogResult.Ok)
    {
        WebFoldersDestPath = filePickerDialog.FileName + "\\";
    }

    filePickerDialog = null;

    return WebFoldersDestPath;
}

OpenFileDialogとSaveFileDialogはの左上隅で自分自身を配置します 最近表示されたウィンドウのクライアント領域。だからあなたはダイアログが作成し、そのダイアログを表示する前に表示したい場所に位置し、新しい不可視のウィンドウを作成します。

Window dialogPositioningWindow = new Window();
dialogPositioningWindow.Left = MainWindow.Left + <left position within main window>;
dialogPositioningWindow.Top  = MainWindow.Top  + <top  position within main window>;
dialogPositioningWindow.Width = 0; 
dialogPositioningWindow.Height = 0; 
dialogPositioningWindow.WindowStyle = WindowStyle.None;
dialogPositioningWindow.ResizeMode = ResizeMode.NoResize;
dialogPositioningWindow.Show();// OpenFileDialog is positioned in the upper-left corner
                               // of the last shown window (dialogPositioningWindow)
Microsoft.Win32.OpenFileDialog dialog = new Microsoft.Win32.OpenFileDialog();
...
if ((bool)dialog.ShowDialog()){
   ...
}
dialogPositioningWindow.Close();

ここで私はそれをやった方法は次のとおりです。

私はOpenFileDialogを表示したいポイントます:

Thread posThread = new Thread(positionOpenDialog);
posThread.Start();

DialogResult dr = ofd.ShowDialog();

再配置コード:

[DllImport("user32.dll", EntryPoint = "FindWindow", SetLastError = true)]
static extern IntPtr FindWindowByCaption(IntPtr ZeroOnly, string lpWindowName);

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
public static extern IntPtr SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int x, int Y, int cx, int cy, int wFlags);


/// <summary>
/// Find the OpenFileDialog window when it appears, and position it so
/// that we can see both dialogs at once.  There is no easier way to
/// do this (&^%$! Microsoft!).
/// </summary>
private void positionOpenDialog ()
{
    int count = 0;
    IntPtr zero = (IntPtr)0;
    const int SWP_NOSIZE = 0x0001;
    IntPtr wind;

    while ((wind = FindWindowByCaption(zero, "Open")) == (IntPtr)0)
        if (++count > 100)
            return;             // Find window failed.
        else
            Thread.Sleep(5);

    SetWindowPos(wind, 0, Right, Top, 0, 0, SWP_NOSIZE);
}

私は「オープン」のタイトルを持つウィンドウを探しスレッドを開始します。 (典型的には3回の反復、または15ミリ秒で発見。)それから得られたハンドルとの位置を設定します。 (位置/サイズパラメータのSetWindowPosのドキュメントを参照してください。)

クルージます。

MSDN上の一つのアプローチのかなり古い例があります。

http://msdn.microsoft.com/en-us/library /ms996463.aspxする

これは、拡張性を可能にする独自のOpenFileDialogクラスを実装するために必要なすべてのコードが含まれます。

この1にBobBの返信のために非常に感謝。さらにいくつかの「落とし穴」があります。あなたはOpenFileDialog1.ShowDialog(PositionForm)を呼び出すときにPositionFormのハンドルを渡す必要がありそうBobBの技術は、すべてのケースで信頼できるものではありません。また、今ではW8.1はそれでSkyDriveの持つ新しいFILEOPENコントロールを起動し、W8.1のFILEOPENコントロールのドキュメントフォルダの場所は現在、ネジ止めされています。だから私は、真のShowHelp =を設定することにより、古いW7コントロールを使用するFILEOPEN frig。

ここに私が使用して終了VB.NETコード、それが助け場合は、コミュニティへの私の貢献はあります。

Private Function Get_FileName() As String

    ' Gets an Input File Name from the user, works with multi-monitors

    Dim OpenFileDialog1 As New OpenFileDialog
    Dim PositionForm As New Form
    Dim MyInputFile As String

    ' The FileDialog() opens in the last Form that was created.  It's buggy!  To ensure it appears in the
    ' area of the current Form, we create a new hidden PositionForm and then delete it afterwards.

    PositionForm.StartPosition = FormStartPosition.Manual
    PositionForm.Left = Me.Left + CInt(Me.Width / 2)
    PositionForm.Top = Me.Top + CInt(Me.Height / 2)
    PositionForm.Width = 0
    PositionForm.Height = 0
    PositionForm.FormBorderStyle = Forms.FormBorderStyle.None
    PositionForm.Visible = False
    PositionForm.Show()

    ' Added the statement "ShowHelp = True" to workaround a problem on W8.1 machines with SkyDrive installed.
    ' It causes the "old" W7 control to be used that does not point to SkyDrive in error.

    OpenFileDialog1.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
    OpenFileDialog1.Filter = "Excel files (*.xls*)|*.xls*|CSV Files (*.csv)|*.csv"
    OpenFileDialog1.FilterIndex = 1
    OpenFileDialog1.RestoreDirectory = True
    OpenFileDialog1.AutoUpgradeEnabled = False
    OpenFileDialog1.ShowHelp = True
    OpenFileDialog1.FileName = ""
    OpenFileDialog1.SupportMultiDottedExtensions = False
    OpenFileDialog1.Title = "Select an Excel or .csv file containing patent data or list of Publication Numbers for your project."

    If OpenFileDialog1.ShowDialog(PositionForm) <> System.Windows.Forms.DialogResult.OK Then
        Console.WriteLine("No file was selected. Please try again!")
        PositionForm.Close()
        PositionForm.Dispose()
        OpenFileDialog1.Dispose()
        Return ""
    End If
    PositionForm.Close()
    PositionForm.Dispose()

    MyInputFile = OpenFileDialog1.FileName
    OpenFileDialog1.Dispose()
    Return MyInputFile

End Function
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top