0

我有一个以 aTabControl tabControl作为主要对象的 Windows 窗体应用程序(.NET Framework 4.8)。我用它来切换到不同的屏幕,并且我有一个下一个上一个按钮,可以使用以下代码选择下一个或上一个选项卡:

private void ButtonNextTab(object sender, EventArgs e)
{
    int index = tabControl.SelectedIndex;
    tabControl.SelectTab(index + 1); // index - 1 for ButtonPreviousTab
}

我通过在以下内容中包含以下内容将我的应用程序设置为 DPI 感知app.config

<System.Windows.Forms.ApplicationConfigurationSection>
   <add key="DpiAwareness" value="PerMonitorV2" />
</System.Windows.Forms.ApplicationConfigurationSection>

在最后一个选项卡上,我有一个 DataGridView。如果我使用按钮准确地转到最后一个选项卡两次,无论我单击按钮的速度有多快,我都会收到以下异常:System.ComponentModel.Win32Exception: 'Error creating window handle.',并且它似乎是在SelectTab方法中抛出的。如果我将 SelectTab 替换为tabControl.SelectedIndex = index + 1.

app.config但是,如果我使用 TabControl 的选项卡多次删除标签或导航到选项卡,则不会发生这种情况。我在第二台显示器上以 100% 缩放创建并运行应用程序,但如果我在笔记本电脑主屏幕上以 125% 缩放运行它,则不会发生问题(尽管有趣的是,应用程序始终以 100% 启动,直到出现 DPI 更改事件通过将应用程序从一个屏幕移动到另一个屏幕来触发)。我只能在我的 100% 屏幕上重现这个问题,而从来没有在我的 125% 屏幕上重现这个问题。如果我将主屏幕上的缩放设置为 100%,问题就会消失,如果两个屏幕都设置为 125%,我也无法重现它。

我找不到有关此问题的任何信息。有没有办法防止它?

异常信息的图像,几乎没有任何有用的信息


更新:我尝试设置DataGridView.DisableHighDpiImprovements"false",但没有解决


更新 2:完整的堆栈跟踪(图像仅显示第一位):

at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.ComboBox.CreateHandle()
at System.Windows.Forms.Control.RecreateHandleCore()
at System.Windows.Forms.ComboBox.RecreateHandleCore()
at System.Windows.Forms.ComboBox.OnFontChanged(EventArgs e)
at System.Windows.Forms.Control.set_Font(Font value)
at System.Windows.Forms.Control.WmDpiChangedBeforeParent(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)

作为参考,这是 datagridview 的样子(删除了标题中的文本),右侧的按钮不是 datagridview 的一部分,而是用于控制当前选定的行。

在此处输入图像描述


更新 3:创建新项目时我无法自己复制它。以不同的 DPI 值(100% 和 125%)重新启动并没有帮助。我发现第一次点击下拉菜单的背景是黑色的。如果将鼠标悬停在某个选项上,它将显示为正常突出显示的选项(蓝色背景和白色文本),直到我再次离开它。这发生在两个屏幕上。

黑色下拉菜单

我还发现,如果我将光标放在 placeholder 的两个文本字段中DataDridViewRow,则不会发生异常。将光标放在其中一个文本字段中后,文本字段本身就像下拉菜单一样显示为黑色,但只有一次(与下拉菜单不同),然后下拉菜单和其他文本框不再是黑色的。这表明占位符行有问题,但我不知道是什么,也不知道它与不同的 DPI 问题有何关系。其中一列还有一个很长的工具提示,我认为可能会导致问题,但删除它什么也没做。


更新 4:如果在表单设计器中将 DataGridView 的 Visible 属性设置为 false,则不会发生错误。这似乎将问题限制在与 DataGridView 和多个屏幕上的不同缩放相关的问题上。我还尝试以编程方式在占位符行的两个文本字段中设置文本,但没有成功。

4

1 回答 1

0

我找到了一种解决方法,如果没有选择任何单元格,则通过手动选择 datagridview 中的第一个文本字段,问题不再发生:

private void ButtonNextTab(object sender, EventArgs e)
{
    int index = tabControl.SelectedIndex;
    if (index == 1 && dataGridView.CurrentCell is null)
    {
        dataGridView.Rows[0].Cells[1].Selected = true;
    }
    tabControl.SelectTab(index + 1);
}

我仍然不知道实际问题是什么,也不知道这种解决方法如何防止这种情况发生,但至少它有效。如果我有时间重写所有内容,我可能会切换到 WPF。如果有人遇到此问题并找出导致问题的原因,请将其添加为答案。

于 2021-04-22T13:40:40.517 回答