【问题标题】:C# WinForm TabControl Formatting IssueC# WinForm TabControl 格式化问题
【发布时间】:2021-10-04 07:58:15
【问题描述】:

当以编程方式将控件添加到选项卡控件时,我一直在使用 Form_Load 事件来创建数据网格视图等内容并将其嵌入到我的 UI 中。我做了一个继承自 DataGridView 的类

class DBDataGridView : DataGridView
{
    public DBDataGridView()
    {
        DoubleBuffered = true;
        AllowUserToAddRows = false;
        AllowUserToDeleteRows = false;
        AllowUserToResizeRows = false;
        AllowUserToOrderColumns = false;
        AllowUserToResizeColumns = false;
        RowHeadersVisible = false;
        AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.AllCells;
        ReadOnly = true;
        Dock = DockStyle.Fill;
        SelectionMode = DataGridViewSelectionMode.FullRowSelect;
        TabStop = false;
    }
}

我稍后在 Form_Load 事件中这样调用它

    private void MainDesignerForm_Load(object sender, EventArgs e)
    {
        DBDataGridView _DGV = new DBDataGridView();

        var listOfOverlays = new List<OverlaySelectionList>()
        {
            new OverlaySelectionList { Description = "Description 1", PartNumber = "123-R1"},
            new OverlaySelectionList { Description = "Description 2", PartNumber = "456-R1"}
        };
        var overlayList = new BindingList<OverlaySelectionList>(listOfOverlays);
        _DGV.DataSource = overlayList;
        Tab_Overlay.Controls.Add(_DGV);
        _DGV.ClearSelection();
    }

此网格视图位于 TabControl 的第三个选项卡上,除了 ClearSelection() 之外,一切都按预期工作。无论我在哪里调用它,它都不会清除 DGV 的初始行选择。但是,如果我从第三个选项卡上的按钮触发相同的代码块,则格式和 ClearSelection() 会按预期运行。

是什么导致了这种行为?

【问题讨论】:

  • 假设 Tab_Overlay 不是选定的标签页,它的所有控件(包括 DGV)都是不可见的(是的,.Visible == false),这会导致 ClearSelection() 无法完成其工作。尝试在_DGV.ClearSelection(); 之前添加yourTabControl.SelectedTab = Tab_Overlay;。然后,如果需要,您可以在之后重置选定的选项卡。
  • TabPages 有时不会完全更新其布局。也许您可以将代码添加到 SelectedIndexChanged 来修复它..
  • 在显示父窗体时未显示的 TabPage 控件不会创建它们的句柄。因此,您可以设置缓存其值的属性,但许多依赖于句柄创建的方法不做任何事情(除了设置/更改某些属性的值,如果这是它们行为的一部分),因为 .Net 实现总是检查如果在执行需要句柄的操作之前创建句柄。
  • 要注意很多 WinForms 控件都是基于 Win32 控件的。因此,底层 Win32 控件会执行许多标准操作。 PInvoking 需要执行许多这些操作。如果您没有句柄,则无法 PInvoke。
  • 您可以强制创建句柄,但您需要考虑性能方面的影响。 TabControl 的 TabPages 的子控件不创建它们的句柄是有原因的。您可以随时查看 (bool hasHandle = [Control].IsHandleCreated;)。或将其强制为_ = [Control].Handle; 或在特定上下文中调用CreateControl()

标签: c# winforms datagridview tabcontrol


【解决方案1】:

感谢 41686d6564 和 Jimi 深入了解为什么会发生这种情况。

重申他们在 cmets 中所说的话:无论它们所属的控件是否处于活动状态,属性的分配似乎都会被缓存(因此,为什么所有大小和格式属性都存在于运行时)。但是,需要句柄的操作(例如 ClearSelection())需要显示控件并处于活动状态,才能观察到预期的行为。

在调用 ClearSelection() 之前将选定的选项卡设置为 DataGridView 的解决方案(或者在我的情况下,我有嵌套的选项卡,所以我必须按照选项卡树来访问 DataGridView 所在的特定选项卡)

所以现在,Load_Form 逻辑的一部分是检查控件的位置,使该选项卡处于活动状态,然后格式化并清除每个要添加的控件的选择。这使得 ClearSelection() 可以按预期工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-07
    • 1970-01-01
    • 1970-01-01
    • 2013-06-06
    相关资源
    最近更新 更多