3

我正在支持使用 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)

这是该片段的代码:

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

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

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

有人有想法么?非常感谢帮助!

4

4 回答 4

7

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

treeView.Font.Dispose();

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

于 2014-08-18T15:07:48.010 回答
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没有连接到 Control 管道,Krypton 框架在尝试更新 KryptonCombBox 控件的 Palette 时存在一些问题。

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

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

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

* 编辑 *

根据 Matao 的问题,我通过删除添加KryptonComboBoxToolStripMenuItem. 相反,为了获得我想要的功能,我只是ToolStripMenuItems在.DropDownItemsmItem

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

于 2014-02-09T18:51:21.487 回答
1

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

于 2021-04-08T13:11:17.690 回答
-2

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

于 2020-06-02T08:11:49.420 回答