System.Windows.forms.SavefileDialog لا يفرض التمديد الافتراضي

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

  •  22-09-2019
  •  | 
  •  

سؤال

أحاول أن أجعل SaveFileDialog و FileOpenDialog فرض امتداد إلى اسم الملف الذي أدخله المستخدم. لقد حاولت استخدام العينة المقترحة في سؤال 389070 لكنه لا يعمل كما هو مقصود:

var dialog = new SaveFileDialog())

dialog.AddExtension = true;
dialog.DefaultExt = "foo";
dialog.Filter = "Foo Document (*.foo)|*.foo";

if (dialog.ShowDialog() == DialogResult.OK)
{
    ...
}

إذا كتب المستخدم النص test في مجلد حيث ملف test.xml يحدث ، سيقترح الحوار الاسم test.xml (بينما أريد فقط أن أرى فقط *.foo في القائمة). أسوأ من ذلك: إذا اختار المستخدم test.xml, ، ثم سأحصل بالفعل test.xml كاسم ملف الإخراج.

كيف يمكنني التأكد من ذلك SaveFileDialog حقًا يسمح للمستخدم فقط بتحديد ملف *.foo ملف؟ أو على الأقل ، أنه يستبدل/يضيف الامتداد عندما ينقر المستخدم Save?

الحلول المقترحة (تنفيذ FileOk معالج الأحداث) لا تفعل سوى جزء من الوظيفة ، حيث أرغب حقًا في تعطيل Save الزر إذا كان اسم الملف يحتوي على امتداد خاطئ.

من أجل البقاء في الحوار و قم بتحديث اسم الملف المعروض في مربع النص في FileOk معالج ، لتعكس اسم الملف الجديد مع الامتداد الصحيح ، راجع السؤال التالي ذي الصلة.

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

المحلول

AFAIK لا توجد طريقة موثوقة لفرض امتداد ملف معين. إنها ممارسة جيدة على أي حال للتحقق من الامتداد الصحيح ، بمجرد إغلاق مربع الحوار وإبلاغ المستخدم بأنه قد حدد ملفًا غير صالح إذا لم يتطابق الامتداد.

نصائح أخرى

يمكنك التعامل مع FileOk الحدث ، وإلغاءه إذا لم يكن الامتداد الصحيح

private saveFileDialog_FileOk(object sender, CancelEventArgs e)
{
    if (!saveFileDialog.FileName.EndsWith(".foo"))
    {
        MessageBox.Show("Please select a filename with the '.foo' extension");
        e.Cancel = true;
    }
}

أقرب ما وصلت إلى هذا هو باستخدام حدث FileoK. علي سبيل المثال:

dialog.FileOk += openFileDialog1_FileOk;

private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e)
{
  if(!dialog.FileName.EndsWith(".foo"))
  { 
     e.Cancel = true;
  }
}

الدفع حدث FileoK على MSDN.

واجهت هذه المشكلة نفسها ، وتمكنت من التحكم في ما تم عرضه من خلال القيام بما يلي:

مع OpenFileDialog ، كان العنصر الأول في سلسلة التصفية هو الافتراضي

openFileDialog1.Filter = "Program x Files (*.pxf)|*.pxf|txt files (*.txt)|*.txt";
openFileDialog1.ShowDialog();

مع SaveFileDialog ، تم استخدام العنصر الثاني في المرشح كإعداد افتراضي:

SaveFileDialog saveFileDialog1 = new SaveFileDialog();

saveFileDialog1.Filter = "txt files (*.txt)|*.txt|Program x Files (*.pxf)|*.pxf";
saveFileDialog1.FilterIndex = 2;
saveFileDialog1.RestoreDirectory = true;

if (saveFileDialog1.ShowDialog() == DialogResult.OK)
{
    if (saveFileDialog1.FileName != null)
    {
        // User has typed in a filename and did not click cancel
        saveFile = saveFileDialog1.FileName;
        MessageBox.Show(saveFile);
        saveCurrentState();

    }
} 

بعد استخدام هذين المرشحين مع المرشحين المعنيين ، حدثت النتائج المتوقعة أخيرًا. بشكل افتراضي ، عندما يحدد المستخدم زر حفظ ويظهر SaveFileDialog ، فإن fileType المحدد هو نوع ملفات البرنامج المحددة في المرشح لـ SaveFileDialog. وبالمثل ، فإن fileType المحدد لـ OpenFileDialog هو نوع ملفات البرنامج X المحددة في المرشح لـ OpenFileDialog.

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

    //this must be ran as administrator due to the change of a registry key, but it does work...

    private void doWork()
    {
        const string lm = "HKEY_LOCAL_MACHINE";
        const string subkey = "\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\AutoComplete";
        const string keyName = lm + subkey;

        int result = (int)Microsoft.Win32.Registry.GetValue(keyName, "AutoComplete In File Dialog", -1);

        MessageBox.Show(result.ToString());

        if(result.ToString() == "-1")
        {
            //-1 means the key does not exist which means we must create one...
            Microsoft.Win32.Registry.SetValue(keyName, "AutoComplete In File Dialog", 0);
            OpenFileDialog ofd1 = new OpenFileDialog();
            ofd1.ShowDialog();
        }
        if (result == 0)
        {
            //The Registry value is already Created and set to '0' and we dont need to do anything
        }
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top