كيفية استبدال اسم الملف في معالج الأحداث savefiledialog.fileok

StackOverflow https://stackoverflow.com/questions/1599511

سؤال

أود تغيير اسم ملف SaveFileDialog في معالج الأحداث المرفق بـ FileOk الحدث ، من أجل استبدال اسم الملف الذي كتبه المستخدم باسم ملف آخر في بعض الحالات ، بينما الحفاظ على الحوار مفتوحًا:

var dialog = new SaveFileDialog();
...
dialog.FileOk +=
    delegate (object sender, CancelEventArgs e)
    {
        if (dialog.FileName.EndsWith (".foo"))
        {
            dialog.FileName = "xyz.bar";
            e.Cancel = true;
        }
    };

يظهر التنقل عبر الكود أن FileName يتم تحديثه بشكل صحيح بالفعل ، ولكن عند إرجاع معالج الحدث ، لا يتغير اسم الملف المعروض في مربع الحوار. لقد رأيت أنه يمكنني من الناحية النظرية استخدام رمز Win32 مثل ما يلي لتغيير اسم الملف في مربع الحوار نفسه:

class Win32
{
   [DllImport("User32")]
   public static extern IntPtr GetParent(IntPtr);

   [DllImport("User32")]
   public static extern int SetDlgItemText(IntPtr, int string, int);

   public const int FileTitleCntrlID = 0x47c;
}

void SetFileName(IntPtr hdlg, string name)
{
    Win32.SetDlgItemText (Win32.GetParent (hdlg), Win32.FileTitleCntrlID, name);
}

ومع ذلك ، ليس لدي أي فكرة عن المكان الذي يمكنني الحصول عليه HDLG المرتبطة SaveFileDialog مثال من. أعلم أنه يمكنني إعادة كتابة الكل SaveFileDialog غلاف نفسي (أو استخدم رمز مثل nuffsavefiledialog أو ال امتداد codeproject من SaveFileDialog) ، لكنني أفضل استخدام فصول WinForms القياسية لأسباب تقنية.

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

المحلول

للحصول على مقبض الحوار الذي استخدمته التفكير ، ثم دعا SetFileName مع هذا المقبض:

dialog.FileOk +=
    delegate (object sender, CancelEventArgs e)
    {
        if (dialog.FileName.EndsWith (".foo"))
        {
            Type type = typeof(FileDialog);
            FieldInfo info = type.GetField("dialogHWnd", BindingFlags.NonPublic 
                                                       | BindingFlags.Instance);
            IntPtr fileDialogHandle = (IntPtr)info.GetValue(dialog);

            SetFileName(fileDialogHandle, "xyz.bar");
            e.Cancel = true;
        }
    };

NB: في فئة Win32 الخاصة بك ، تحتاج فقط إلى تحديد وظيفة setDlgItemText (ليست هناك حاجة لذلك GetParent) وتمرير مقبض الحوار:

    [DllImport("User32")]
    public static extern int SetDlgItemText(IntPtr hwnd, int id, string title);

    public const int FileTitleCntrlID = 0x47c;

    void SetFileName(IntPtr hdlg, string name)
    {
        SetDlgItemText(hdlg, FileTitleCntrlID, name);
    }

تعديل:

للحصول على الكود السابق يعمل على Windows 7 (أعتقد أيضًا؟) ، قم بتعيين خاصية مربع الحوار ShowHelp إلى true:

dialog.ShowHelp = true;

سيتغير المظهر قليلاً ، لكنني لا أعتقد أنها مشكلة كبيرة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top