我正在支持使用 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 代码中。还有一个通过我的一个类(class):
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)

这是该片段的代码:
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 句柄泄漏还是只是不好配置由用户做一些不寻常的事情触发的某处。

有人有主意吗?非常感谢帮助!

最佳答案

我正在使用 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 没有连接到 Control 管道,Krypton 框架在尝试更新 KryptonCombBox 控件的 Palette 时遇到了一些问题。

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

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

我希望这能让您对您的问题有所了解。

* 编辑 *

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

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

关于.net - 来自 Font.GetHeight(图形图形)的 Windows 窗体 "System.ArgumentException: Parameter is not valid",我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/15652756/

10-13 09:43