سؤال

أي الحوار مخصص (شكل) في تطبيق WinForm لا يمكن تعيين حجم وموضع قبل عرضه مع:

form.StartPosition = FormStartPosition.Manual;
form.DesktopBounds = MyWindowPosition;

هذا مهم بشكل خاص عند التعامل مع أجهزة عرض متعددة.بدون هذا الكود عند فتح مربع حوار من أحد التطبيقات التي قمت بسحبها إلى شاشة ثانية الحوار يظهر على جهاز العرض الأساسي.وهذا يمثل ضعف تجربة المستخدم.

وأنا أتساءل إذا كان هناك أي السنانير إلى تعيين موضع القياسية .صافي OpenFileDialog و SaveFileDialog (التي ليس لها StartPosition الملكية).

هل كانت مفيدة؟

المحلول

أظن أن أفضل ما يمكنك فعله هو تأكد من استخدام الزائد من ShowDialog هذا يقبل an. IWin32Window لاستخدام الوالد. هذه ربما ساعده في اختيار موقع مناسب؛ اكثر شيوعا:

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

نصائح أخرى

الدفع هذه المقالة على codeproject. مقتطفات:

هنا عندما يأتي Handy .Net Nativewindow في الصورة، A NativeWindow عبارة عن مجمع النافذة حيث يعالج الرسائل المرسلة عن طريق المقبض المرتبط به. إنه يخلق NativeWindow وربط مقبض OpenFileWindow لذلك. من هذه النقطة، سيتم إعادة توجيه كل رسالة تم إرسالها إلى OpenFileWindow إلى طريقة WNDPROC الخاصة بنا في NativeWindow بدلا من ذلك، يمكننا إلغاء أو تعديل أو السماح لهم بالمرور.

في WNDProc لدينا، نحن نعالج الرسالة WM_WindowPoschanging. إذا افتتح مربع الحوار "فتح"، فسنقوم بتغيير الحجم الأفقي أو الرأسي الأصلي اعتمادا على Settlocation المحرز من قبل المستخدم. سوف يزيد حجم النافذة التي سيتم إنشاؤها. يحدث هذا مرة واحدة فقط عند فتح عنصر التحكم.

أيضا، سنقوم بمعالجة الرسالة 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 لمعلمات الموضع / الحجم.)

kludgy.

هناك مثال قديم نهج واحد على MSDN.

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

ويشمل كل الكود اللازم لتنفيذ فئة OpenFileDialog الخاصة بك التي تسمح بالاسعة.

ممتن جدا BobB رد على هذا واحد.هناك عدد قليل من أكثر "gotchas".لديك لتمرير مقبض PositionForm عند استدعاء OpenFileDialog1.ShowDialog(PositionForm) وإلا BobB تقنية لا يمكن الاعتماد عليها في جميع الحالات.أيضا الآن W8.1 تطلق جديد فوقfileopen التحكم مع SkyDrive في مجلد المستندات في الموقع W8.1 فوقfileopen السيطرة الآن مشدود.لذا تفعلي [ذلك] فوقfileopen استخدام القديم W7 التحكم عن طريق وضع ShowHelp = True.

هنا 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