【问题标题】:C# saveFileDialog open twiceC# saveFileDialog 打开两次
【发布时间】:2018-11-04 18:49:21
【问题描述】:

我有一个数据表 (dt) 和一个用于将数据导出到 excel 的按钮。

我正在使用 ClosedXML 完成工作。

但是,当我单击导出按钮时,我得到了第一个 saveFileDialog,然后单击 OK 后,我得到了第二个 saveFileDialog。在此之后,文件被正确导出。

所以,代码...

这是按钮导出操作的主要代码。我正在使用 saveFileDIalog 来允许用户选择保存文件目录。

private void exportarToolStripMenuItem_Click(object sender, EventArgs e)
    {
        if(saveFileDialog.ShowDialog() == DialogResult.OK)
        {
            FileInfo fileInfo = new FileInfo(saveFileDialog.FileName);
            SaveToExcel(dt, fileInfo);
        }
    }

然后,方法

public static void SaveToExcel(System.Data.DataTable dt, FileInfo outputFile)
    {
        XLWorkbook wb = new XLWorkbook();
        var worksheet = wb.Worksheets.Add(dt, "ResultTable");

        using (MemoryStream memoryStream = GetStream(wb))
        {
            File.WriteAllBytes(outputFile.FullName, memoryStream.ToArray());
        }
    }

还有内存流

public static MemoryStream GetStream(XLWorkbook excelWorkbook)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            excelWorkbook.SaveAs(stream, new SaveOptions { EvaluateFormulasBeforeSaving = false, GenerateCalculationChain = false, ValidatePackage = false,  });
            return stream;
        }
    }

请有人帮我看看为什么我得到 2 个 saveFileDialog 吗?

谢谢。

【问题讨论】:

  • 你调试过这个吗?您有多确定该事件没有被触发两次?请注意,如果是这种情况,您将看不到两个文件,因为一次会覆盖其他文件。对话框是唯一明显多次触发效果的效果。
  • 在向用户显示对话框之前读取文件名也很奇怪。用户是否无法指定文件名?因为如果他们能够做到,那么他们可能已经更改了对话框中的文件名。
  • 在SaveToExcel函数中,为什么要调用两次GetStream?
  • 另外..为什么要在退货时处理MemoryStream?你应该在使用它的函数中处理它(就像你正在做的那样)。
  • 标准原因是不小心订阅了两次 Click 事件。

标签: c# memorystream savefiledialog


【解决方案1】:

我发现了一个问题;我添加了一些 cmets:

private void exportarToolStripMenuItem_Click(object sender, EventArgs e)
{
    string filename = saveFileDialog.FileName; // what is this for? I would remove it.
    if(saveFileDialog.ShowDialog() == DialogResult.OK)
    {
        // problem in the following line, explained below
        string path = Path.GetFullPath(filename);
        // you should be picking the saveFileDialog.FileName at this point  to get
        // the user selection, not the filename variable you got before;
        // moreover, the saveFileDialog.FileName is already a full path, no need to
        // call the Path.GetFullPath method
        FileInfo fileInfo = new FileInfo(path);
        SaveToExcel(dt, fileInfo);
    }
}

编辑:其他用户的cmets报其他问题(MemoryStream管理不好)

【讨论】:

  • 在第一个 savefileDialog 弹出窗口中,文件被保存。在第二个弹出窗口中,文件被覆盖。那么,为什么我会收到 2 个弹出窗口?根据您的回答,我在第一篇文章中更改了代码。
  • 那么,正如@Hans Passant 所注意到的,您可能已经注册了两次 exportarToolStripMenuItem_Click 事件处理程序。它发生了;也许您通过 Visual Studio 在 .designer 代码中注册了它,然后在您的代码中重新添加了它。检查一下。
  • 是的...在表单构造函数中忘记了这个... exportarToolStripMenuItem.Click += new EventHandler(this.exportarToolStripMenuItem_Click);现在只显示一个弹出窗口。谢谢大家!
  • 最后,让我补充一点:一些 try-catch 是可取的。如果用户选择了他可能已在 Excel 中打开的现有文件,您可能会收到拒绝访问异常。很遗憾你的程序崩溃了。最好将事件处理程序中的代码放入 try-catch 块中,并在出现任何异常时提供 MessageBox 警报。
猜你喜欢
  • 1970-01-01
  • 2019-11-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 2021-09-16
  • 1970-01-01
相关资源
最近更新 更多