如何在SaveFileDialog.FileOk事件处理程序中替换FileName [英] How to replace FileName in SaveFileDialog.FileOk event handler

查看:157
本文介绍了如何在SaveFileDialog.FileOk事件处理程序中替换FileName的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在附加到FileOk事件的事件处理程序中更改SaveFileDialog的文件名,以便在某些情况下将用户键入的文件名替换为另一个文件名,而保持对话框打开:

I'd like to change the file name of the SaveFileDialog in the event handler attached to the FileOk event, in order to replace the file name typed in by the user with another file name in some cases, while keeping the dialog open:

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代码来更改对话框本身中的文件名:

Stepping through the code shows that the FileName gets indeed properly updated, but when the event handler returns, the file name displayed in the dialog does not change. I've seen that I could theoretically use Win32 code like the following to change the file name in the dialog itself:

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);
}

但是,我不知道从哪里可以获取与SaveFileDialog实例关联的HDLG.我知道我可以自己重写整个SaveFileDialog包装器(或使用代码例如NuffSaveFileDialog SaveFileDialog的CodeProject扩展),但我出于技术原因,宁愿使用标准WinForms类.

However, I've no idea where I can get the HDLG associated to the SaveFileDialog instance from. I know I can rewrite the whole SaveFileDialog wrapper myself (or use code like NuffSaveFileDialog or the CodeProject extension of SaveFileDialog), but I'd prefer to use the standard WinForms classes for technical reasons.

推荐答案

获取我使用反射的对话框句柄,然后使用该句柄调用SetFileName:

to get the dialog handle I used reflection, then called SetFileName with that handle:

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;
        }
    };

注意:在Win32类中,您只需要定义SetDlgItemText函数(无需GetParent)并将对话框句柄传递给它即可:

N.B.: in your Win32 class you only need to define SetDlgItemText function (there is no need to GetParent) and pass to it the dialog handle:

    [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上运行(我也认为是Vista吗?),请将对话框的属性ShowHelp设置为true:

dialog.ShowHelp = true;

外观会有所变化,但我认为没什么大不了的.

the appearance will change a little bit, but I don't think it's a big deal.

这篇关于如何在SaveFileDialog.FileOk事件处理程序中替换FileName的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆