【问题标题】:Windows Forms "System.ArgumentException: Parameter is not valid" from Font.GetHeight(Graphics graphics)来自 Font.GetHeight(图形图形)的 Windows 窗体“System.ArgumentException:参数无效”
【发布时间】:2013-03-27 05:59:12
【问题描述】:

我正在支持使用 dotnet 3.5 和 ComponentFactory Krypton v4.4.0.0 的 winforms 应用程序,我最近实现了 AppDomain.CurrentDomain.UnhandledException 和 Application.ThreadException 处理程序来通知我客户端上发生的异常,并发现了很多错误显示在日志中。此刻,这个正在我的脑海中:

System.ArgumentException: Parameter is not valid.
 at System.Drawing.Font.GetHeight(Graphics graphics)
 at System.Drawing.Font.GetHeight()
 at System.Drawing.Font.get_Height()
 at System.Windows.Forms.Control.set_Font(Font value)
 at System.Windows.Forms.DataGridViewComboBoxEditingControl.ApplyCellStyleToEditingControl(DataGridViewCellStyledataGridViewCellStyle)
 at System.Windows.Forms.DataGridView.BeginEditInternal(Boolean selectAll)
 at System.Windows.Forms.DataGridView.ProcessKeyEventArgs(Message& m)
 at System.Windows.Forms.Control.ProcessKeyMessage(Message& m)
 at System.Windows.Forms.Control.WmKeyChar(Message& m)
 at System.Windows.Forms.Control.WndProc(Message& m)
 at System.Windows.Forms.DataGridView.WndProc(Message& m)
 at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
 at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
 at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam,IntPtr lparam)

请注意,堆栈跟踪完全在 Windows 代码中。还有一个通过我的一个类:

System.ArgumentException: Parameter is not valid.
  at System.Drawing.Font.GetHeight(Graphics graphics)
  at System.Drawing.Font.GetHeight()
  at System.Drawing.Font.get_Height()
  at System.Windows.Forms.Control.set_Font(Font value)
  at MyOrg.MyApp.WindowsClient.GuiControls.MaskedTextBoxEditingControl.ApplyCellStyleToEditingControl(DataGridViewCellStyledataGridViewCellStyle)
  at System.Windows.Forms.DataGridView.BeginEditInternal(Boolean selectAll)
  at System.Windows.Forms.DataGridView.ProcessKeyEventArgs(Message& m)
  at System.Windows.Forms.Control.ProcessKeyMessage(Message& m)
  at System.Windows.Forms.Control.WmKeyChar(Message& m)
  at System.Windows.Forms.Control.WndProc(Message& m)
  at System.Windows.Forms.DataGridView.WndProc(Message& m)
  at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
  at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
  at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

这是该 sn-p 的代码:

public void ApplyCellStyleToEditingControl(DataGridViewCellStyle dataGridViewCellStyle)
{
  this.Font = dataGridViewCellStyle.Font;
  this.ForeColor = dataGridViewCellStyle.ForeColor;
  this.BackColor = dataGridViewCellStyle.BackColor;
  this.TextAlign = translateAlignment(dataGridViewCellStyle.Alignment);
}

这并没有告诉我太多。

“System.ArgumentException:参数无效。”错误非常可悲,让我几乎无法继续,但使用 dotPeek 我查看了 Font.Get_Height(Graphics g) 的代码,发现这是一个 GDI+ 错误,特别是 GetFontHeight:

public float GetHeight(Graphics graphics)
{
  if (graphics == null)
  {
    throw new ArgumentNullException("graphics");
  }
  else
  {
    float size;
    int fontHeight = SafeNativeMethods.Gdip.GdipGetFontHeight(new HandleRef((object) this, this.NativeFont), new HandleRef((object) graphics, graphics.NativeGraphics), out size);
    if (fontHeight != 0)
      throw SafeNativeMethods.Gdip.StatusException(fontHeight);
    else
      return size;
  }
}

这是 GDI+ 方法: http://www.jose.it-berater.org/gdiplus/reference/flatapi/font/gdipgetfontheight.htm

我的状态错误是 Invalidparameter,如此处所述: http://msdn.microsoft.com/en-us/library/windows/desktop/ms534175(v=vs.85).aspx

不幸的是,这些都不能帮助我解决 Graphics 对象的问题。这是来自现场用户未处理的异常。我最近有一个内存泄漏,这是由泄漏的 EventHandler 和消耗所有可用的 GDI 句柄引起的,但我已经解决了这个问题,所以现在我不确定这是内存泄漏、GDI 句柄泄漏还是只是坏的配置某个由用户做一些不寻常的事情触发的地方。

有人有什么想法吗?非常感谢您的帮助!

【问题讨论】:

  • 如果你尝试this.Font = new Font(dataGridViewCellStyle.Font);会怎样
  • 当调用堆栈不通过我的代码时,这将如何提供帮助?我感觉有其他东西正在破坏图形对象,但我不知道是什么......
  • 我遇到了同样的问题。你在某些方面解决了吗?
  • 不,还在等待:-(如果我知道如何解决它,我会发布!
  • 另外,您使用的是 Krypton 还是其他第三方控件库?

标签: .net winforms gdi+ argumentexception


【解决方案1】:

我刚刚遇到了这个问题,花了几个小时才弄清楚,我将其追溯到代码库的其他部分,从控件获取对 Font 的引用,然后对其执行 Dispose()字体。我能够通过创建一个 Windows 窗体项目、添加一个 TreeView 和一个 DataGridView 并在 TreeView 上执行它来重现这一点

treeView.Font.Dispose();

希望我的发现对遇到此问题的任何人都有帮助。

【讨论】:

  • 谢谢!我现在要检查我的整个项目并尝试找到我们正在处理字体的任何地方。嗯,除了通常的设计器文件(我能找到!)之外没有参考,臭虫:-/
  • 我们在哪里使用Dispose()函数?
  • 我可以确认这个问题是由于我尝试使用之前处理过的字体引起的。就我而言,它需要将 ComboBox 的 Font 属性设置为已处置的字体。
  • 我在 datagridview 中更改字体时遇到了同样的问题。不幸的是,我正在使用 (Font font = new Font("Microsoft Sans Serif", 9, FontStyle.Regular))
【解决方案2】:

我正在使用 Krypton 4.4 和 .NET 4.0,并且遇到了相同的行为,但它处理的是 KryptonComboBox。像 matao 一样,错误似乎根本不是通过我的代码,而是通过 Krypton 框架和 .NET 本身。

在对 Krypton 源代码进行一些调查并查看引发此错误时的堆栈跟踪后,我注意到 KryptonComboBox(或 Krypton 框架的一部分)附加到 Microsoft.Win32.SystemEvents.OnUserPreferenceChanged 事件让我思考。也许这没有通过我的代码的原因是这个事件是在某个时候从操作系统触发的。它仍然没有解释为什么会抛出错误,但我开始以不同的方式思考这个问题。

现在,每当发生此错误时,它总是会遍历 KryptonComboBox,但无论如何都不一致。它实际上很难调用。但是,由于 OnUserPreferenceChanged 事件触发,我开始研究诸如全局策略更改或会触发该事件的东西。幸运的是,我注意到如果我运行我的 WinForms 应用程序并启动 Internet Explorer,我可以可靠地弹出这个异常。不要问我为什么会这样,但显然启动 IE 会以某种方式触发 OnUserPreferenceChanged 事件。

现在我有了触发异常的可靠方法,我开始在我的代码中查看 KryptonComboBox 实例并注释掉整个模块,看看我是否可以让这个异常返回。最终,我发现了这个错误,结果是我的 WinForms 应用程序中的代码连接方式出现了错误。具体来说,这里是错误:

    KryptonComboBox detailView = new KryptonComboBox();
    detailView.Sorted = true;
    detailView.Text = "View";
    detailView.Items.Add(new KryptonListItem("Details", "Detail View"));
    detailView.Items.Add(new KryptonListItem("List", "List"));
    detailView.Items.Add(new KryptonListItem("Tile", "Tiles"));

    ToolStripMenuItem mItem = new ToolStripMenuItem();
    mItem.Tag = detailView;
    mItem.Text = detailView.Text;
    mItem.Click += new EventHandler(contextItem_Click);

我的猜测是,因为detailView 没有连接到控制管道,Krypton 框架在尝试更新 KryptonCombBox 控件的 Palette 时遇到了一些问题。

我注意到一个奇怪的细微差别是,在 Krypton 框架内引发第一个异常后,它似乎破坏了 Graphics 对象。随后调用更新 Palette(切换 Krypton 控件的颜色),错误总是会抛出,但会通过调用堆栈中的不同区域(总是从我的源代码中的某个位置启动)。

Matao,我不确定这是否能回答您的问题,但我相信您可能对如何在 DataGridView 中连接控件有一些问题。也许您正在将控件与 DataGridView 中某物上的 Tag 属性相关联?

我希望这能让您深入了解您的问题。

* 编辑 *

根据 Matao 的问题,我通过删除将 KryptonComboBox 添加到 ToolStripMenuItem 的 Tag 属性的代码来解决问题。相反,为了获得我想要的功能,我只是在mItemDropDownItems 属性中添加了一些额外的ToolStripMenuItems

我会查看您的源代码以查找未添加到控制管道的任何动态创建的控件。

【讨论】:

  • 呸!老实说我放弃了这个,谢谢你的回答!我目前实际上正在从事另一个项目,但我会将您的答案标记为已接受。你的理论听起来不错,很可能我在某个地方的 DataGridViews 中犯了一个错误。我应该寻找什么,我动态创建的控件可能不是控制管道的一部分?我的一个屏幕上有一个 TooStripMenuItem,但不是我通常看到此错误的那个。你是如何修复这个错误的?
  • “我动态创建的控件可能不是控制管道的一部分?”...是的。我相信这是我的问题的主要原因。
【解决方案3】:

对我来说这是因为 DefaultFont 的 Dispose()

【讨论】:

    【解决方案4】:

    不要将 DataGrid 视图停靠到父布局

    【讨论】:

      猜你喜欢
      • 2013-08-03
      • 2013-02-08
      • 2020-04-16
      • 1970-01-01
      • 1970-01-01
      • 2011-11-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多