winforms 如果应用程序在外部监视器上打开,则在DataGridView组合框单元格中选择项目时应用程序崩溃

2w2cym1i  于 2023-01-31  发布在  其他
关注(0)|答案(1)|浏览(107)

我有一个应用程序,我写了几年前使用Winforms和C#,最近我遇到了一个奇怪的错误。当选择一个项目从datagridview组合框单元格的应用程序崩溃的错误"系统. OutOfMemoryException:组合框""中的多个项和下面的堆栈跟踪:

at System.Windows.Forms.ComboBox.NativeAdd(Object item)
   at System.Windows.Forms.ComboBox.OnHandleCreated(EventArgs e)
   at System.Windows.Forms.Control.WmCreate(Message& m)
   at System.Windows.Forms.Control.WndProc(Message& m)
   at System.Windows.Forms.ComboBox.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.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

我没有台式电脑可用,只有笔记本电脑,这似乎只有当应用程序是在外部显示器上打开时才会发生,因为在内置屏幕上它工作正常。
我试图将我的外部显示器标记为主屏幕,这样应用程序就会默认在上面打开,因为我认为这可能与此有关,但问题仍然是一样的。
我还尝试添加一个虚拟组合框列到不太复杂的表单控制器,然后在出现问题的地方,同样的事情发生了。

    • 更新日期:**

我已经取得了一些进展。显然,当外部显示器的比例设置与内置显示器的比例设置不同时,就会出现错误。如果有人能解释为什么会出现这种情况,以及如何在我的应用程序代码中修复它,那就太好了。
有时在调试过程中,错误会立即出现在应用程序的主入口点,在这些情况下,我使用Visual Studio winforms设计器预先在组合框列中创建项目列表,在其他情况下,组合框单元格有一个数据表作为源,数据网格视图有自己的数据表作为源。因此,在选择一个项目后,我使用以下函数手动同步它们,在调用DataGridView.EndEdit()后发生错误:

private void DGVAndDataSourceSync(DataGridViewComboBoxEditingControl senderCB, int dgvDtColumn)
        {
            try
            {
                DataRow drCBItemSource = ((DataTable)senderCB.DataSource).Rows[senderCB.SelectedIndex];
                ((DataRowView)senderCB.EditingControlDataGridView.CurrentRow.DataBoundItem).Row[dgvDtColumn] = drCBItemSource[DT_KEY_FIELD_COLUMN];
                _ = senderCB.EditingControlDataGridView.EndEdit();
            }

            catch (Exception ex) { throw ex; }
        }
    • 第二次更新**

我继续试验我的应用程序和另一个演示程序,我做了什么,但一个datagridview只包含一个combobox列.我发现,当我去我的app.manifest的以下行:

<!-- Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />>

并注解掉带有supportedOS标签的行,bug消失了。我不明白为什么会发生这种情况,如果有人知道解释它,那就太好了

xesrikrc

xesrikrc1#

这与内存不足无关
下面是抛出此错误的代码

int insertIndex = unchecked( (int) (long)SendMessage(NativeMethods.LB_ADDSTRING, 0, GetItemText(item)));
      ...
      if (insertIndex == NativeMethods.LB_ERR) {
            // On some platforms (e.g. Win98), the ListBox control
            // appears to return LB_ERR if there are a large number (>32000)
            // of items. It doesn't appear to set error codes appropriately,
            // so we'll have to assume that LB_ERR corresponds to item
            // overflow.
            //
            throw new OutOfMemoryException(SR.GetString(SR.ListBoxItemOverflow));
        }

我在评论中发表的一篇文章说,这是由于在调用GetItemText期间调用tostring时,某个项返回null造成的
https://www.csharp411.com/combobox-exception-too-many-items-in-the-combo-box/

相关问题