天道酬勤,学无止境

Winforms TableLayoutPanel以编程方式添加行(Winforms TableLayoutPanel adding rows programmatically)

问题

我已经为此进行了一段时间的战斗,并且发现许多其他人也为TableLayoutPanel(.net 2.0 Winforms)感到挣扎。

问题

我正在尝试采用“空白” tablelayoutpanel,其中定义了10列,然后在运行时以编程方式添加控件行(即,每个单元格一个控件)。

可能有人以为它应该像

myTableLayoutPanel.Controls.Add(myControl, 0 /* Column Index */, 0 /* Row index */);

但这(对我而言)不会添加行。 所以也许添加一个行样式

myTableLayoutPanel.RowStyles.Clear();
myTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 30F));

但这也不起作用。 我进行了挖掘,发现myTableLayoutPanel.RowCount用法在设计时间与运行时间之间发生了变化,因此进行了myTableLayoutPanel.RowCount++; 实际上并没有添加另一行,甚至没有为它添加RowStyle条目之前/之后!

我遇到的另一个相关问题是控件将被添加到显示中,但是它们都只是在TableLayoutPanel的0,0点处呈现,此外,它们甚至不被限制在应该被认为是的Cell范围内显示在其中(即Dock = DockStyle.Fill,它们仍然显得太大/太小)。

有人在运行时添加行和控件的工作示例吗?

回答1

我上周刚做过。 将TableLayoutPanel上的GrowStyle设置为AddRowsAddColumns ,那么您的代码应该可以工作:

// Adds "myControl" to the first column of each row
myTableLayoutPanel.Controls.Add(myControl1, 0 /* Column Index */, 0 /* Row index */);
myTableLayoutPanel.Controls.Add(myControl2, 0 /* Column Index */, 1 /* Row index */);
myTableLayoutPanel.Controls.Add(myControl3, 0 /* Column Index */, 2 /* Row index */);

这是一些似乎与您正在执行的工作代码类似的代码:

    private Int32 tlpRowCount = 0;

    private void BindAddress()
    {
        Addlabel(Addresses.Street);
        if (!String.IsNullOrEmpty(Addresses.Street2))
        {
            Addlabel(Addresses.Street2);
        }
        Addlabel(Addresses.CityStateZip);
        if (!String.IsNullOrEmpty(Account.Country))
        {
            Addlabel(Address.Country);
        }
        Addlabel(String.Empty); // Notice the empty label...
    }

    private void Addlabel(String text)
    {            
        label = new Label();
        label.Dock = DockStyle.Fill;
        label.Text = text;
        label.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
        tlpAddress.Controls.Add(label, 1, tlpRowCount);
        tlpRowCount++;
    }

TableLayoutPanel总是适合我的尺寸。 在上面的示例中,我要提交的地址卡可能会增加或缩小,具体取决于拥有第二个地址行的帐户或一个国家/地区。 因为表格布局面板的最后一行或最后一列将伸展,所以我在其中放置了空标签以强制添加新的空行,然后所有内容都很好地对齐。

这是设计器代码,因此您可以看到我开始的表格:

        //
        // tlpAddress
        // 
        this.tlpAddress.AutoSize = true;
        this.tlpAddress.BackColor = System.Drawing.Color.Transparent;
        this.tlpAddress.ColumnCount = 2;
        this.tlpAddress.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 25F));
        this.tlpAddress.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
        this.tlpAddress.Controls.Add(this.pictureBox1, 0, 0);
        this.tlpAddress.Dock = System.Windows.Forms.DockStyle.Fill;
        this.tlpAddress.Location = new System.Drawing.Point(0, 0);
        this.tlpAddress.Name = "tlpAddress";
        this.tlpAddress.Padding = new System.Windows.Forms.Padding(3);
        this.tlpAddress.RowCount = 2;
        this.tlpAddress.RowStyles.Add(new System.Windows.Forms.RowStyle());
        this.tlpAddress.RowStyles.Add(new System.Windows.Forms.RowStyle());
        this.tlpAddress.Size = new System.Drawing.Size(220, 95);
        this.tlpAddress.TabIndex = 0;
回答2

这是一个怪异的设计,但是TableLayoutPanel.RowCount属性不能反映RowStyles集合的计数,对于ColumnCount属性和ColumnStyles集合也是如此。

什么我发现我需要在我的代码是手动更新RowCount / ColumnCount更改后RowStyles / ColumnStyles

这是我使用的代码示例:

    /// <summary>
    /// Add a new row to our grid.
    /// </summary>
    /// The row should autosize to match whatever is placed within.
    /// <returns>Index of new row.</returns>
    public int AddAutoSizeRow()
    {
        Panel.RowStyles.Add(new RowStyle(SizeType.AutoSize));
        Panel.RowCount = Panel.RowStyles.Count;
        mCurrentRow = Panel.RowCount - 1;
        return mCurrentRow;
    }

其他想法

  • 我从未使用过DockStyle.Fill来使控件填充Grid中的单元格; 我通过设置控件的Anchors属性来完成此操作。

  • 如果要添加很多控件,请确保在流程周围调用SuspendLayoutResumeLayout ,否则在添加每个控件后重新放置整个表单时,运行速度会很慢。

回答3

这是将新行添加到两列TableLayoutColumn的代码:

private void AddRow(Control label, Control value)
{
    int rowIndex = AddTableRow();
    detailTable.Controls.Add(label, LabelColumnIndex, rowIndex);
    if (value != null)
    {
        detailTable.Controls.Add(value, ValueColumnIndex, rowIndex);
    }
}

private int AddTableRow()
{
    int index = detailTable.RowCount++;
    RowStyle style = new RowStyle(SizeType.AutoSize);
    detailTable.RowStyles.Add(style);
    return index;
}

标签控件在左列中,而值控件在右列中。 控件通常为Label类型,其AutoSize属性设置为true。

我认为这没什么大不了的,但是作为参考,这是设置了detailTable的设计器代码:

this.detailTable.ColumnCount = 2;
this.detailTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.detailTable.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
this.detailTable.Dock = System.Windows.Forms.DockStyle.Fill;
this.detailTable.Location = new System.Drawing.Point(0, 0);
this.detailTable.Name = "detailTable";
this.detailTable.RowCount = 1;
this.detailTable.RowStyles.Add(new System.Windows.Forms.RowStyle());
this.detailTable.Size = new System.Drawing.Size(266, 436);
this.detailTable.TabIndex = 0;

这一切都很好。 您应该意识到,使用Controls属性动态地从TableLayoutPanel布置控件似乎存在一些问题(至少在某些框架版本中)。 如果您需要删除控件,建议您放置整个TableLayoutPanel并创建一个新的。

回答4

创建一个具有两列的表格布局面板,并将其命名为tlpFields

然后,只需将新控件添加到表布局面板中(在本例中,我在第1列中添加了5个标签,在第2列中添加了5个文本框)。

tlpFields.RowStyles.Clear();  //first you must clear rowStyles

for (int ii = 0; ii < 5; ii++)
{
    Label l1= new Label();
    TextBox t1 = new TextBox();

    l1.Text = "field : ";

    tlpFields.Controls.Add(l1, 0, ii);  // add label in column0
    tlpFields.Controls.Add(t1, 1, ii);  // add textbox in column1

    tlpFields.RowStyles.Add(new RowStyle(SizeType.Absolute,30)); // 30 is the rows space
}

最后,运行代码。

回答5

我只是查看了我的代码。 在一个应用程序中,我只添加了控件,但未指定索引,完成后,我仅遍历行样式并将大小类型设置为AutoSize。 因此,仅添加它们而不指定索引似乎可以按预期添加行(前提是GrowStyle设置为AddRows)。

在另一个应用程序中,我清除控件并将RowCount属性设置为所需的值。 这不会添加RowStyles。 然后,我添加控件,这次指定索引,并添加新的RowStyle( RowStyles.Add(new RowStyle(...) ),这也有效。

因此,选择这些方法之一,它们都会起作用。 我记得桌子布局面板让我头疼。

回答6
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim dt As New DataTable
        Dim dc As DataColumn
        dc = New DataColumn("Question", System.Type.GetType("System.String"))
        dt.Columns.Add(dc)

        dc = New DataColumn("Ans1", System.Type.GetType("System.String"))
        dt.Columns.Add(dc)
        dc = New DataColumn("Ans2", System.Type.GetType("System.String"))
        dt.Columns.Add(dc)
        dc = New DataColumn("Ans3", System.Type.GetType("System.String"))
        dt.Columns.Add(dc)
        dc = New DataColumn("Ans4", System.Type.GetType("System.String"))
        dt.Columns.Add(dc)
        dc = New DataColumn("AnsType", System.Type.GetType("System.String"))
        dt.Columns.Add(dc)


        Dim Dr As DataRow
        Dr = dt.NewRow
        Dr("Question") = "What is Your Name"
        Dr("Ans1") = "Ravi"
        Dr("Ans2") = "Mohan"
        Dr("Ans3") = "Sohan"
        Dr("Ans4") = "Gopal"
        Dr("AnsType") = "Multi"
        dt.Rows.Add(Dr)

        Dr = dt.NewRow
        Dr("Question") = "What is your father Name"
        Dr("Ans1") = "Ravi22"
        Dr("Ans2") = "Mohan2"
        Dr("Ans3") = "Sohan2"
        Dr("Ans4") = "Gopal2"
        Dr("AnsType") = "Multi"
        dt.Rows.Add(Dr)
        Panel1.GrowStyle = TableLayoutPanelGrowStyle.AddRows
        Panel1.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single
        Panel1.BackColor = Color.Azure
        Panel1.RowStyles.Insert(0, New RowStyle(SizeType.Absolute, 50))
        Dim i As Integer = 0

        For Each dri As DataRow In dt.Rows



            Dim lab As New Label()
            lab.Text = dri("Question")
            lab.AutoSize = True

            Panel1.Controls.Add(lab, 0, i)


            Dim Ans1 As CheckBox
            Ans1 = New CheckBox()
            Ans1.Text = dri("Ans1")
            Panel1.Controls.Add(Ans1, 1, i)

            Dim Ans2 As RadioButton
            Ans2 = New RadioButton()
            Ans2.Text = dri("Ans2")
            Panel1.Controls.Add(Ans2, 2, i)
            i = i + 1

            'Panel1.Controls.Add(Pan)
        Next
回答7

这非常适合在TableLayoutPanel中添加行和控件。

在设计页面中定义一个包含3列的空白Tablelayoutpanel

    Dim TableLayoutPanel3 As New TableLayoutPanel()

    TableLayoutPanel3.Name = "TableLayoutPanel3"

    TableLayoutPanel3.Location = New System.Drawing.Point(32, 287)

    TableLayoutPanel3.AutoSize = True

    TableLayoutPanel3.Size = New System.Drawing.Size(620, 20)

    TableLayoutPanel3.ColumnCount = 3

    TableLayoutPanel3.CellBorderStyle = TableLayoutPanelCellBorderStyle.Single

    TableLayoutPanel3.BackColor = System.Drawing.Color.Transparent

    TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 26.34146!))

    TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Percent, 73.65854!))

    TableLayoutPanel3.ColumnStyles.Add(New ColumnStyle(SizeType.Absolute, 85.0!))

    Controls.Add(TableLayoutPanel3)

创建一个按钮btnAddRow以在每次单击时添加行

     Private Sub btnAddRow_Click(sender As System.Object, e As System.EventArgs) Handles btnAddRow.Click

          TableLayoutPanel3.GrowStyle = TableLayoutPanelGrowStyle.AddRows

          TableLayoutPanel3.RowStyles.Add(New RowStyle(SizeType.Absolute, 20))

          TableLayoutPanel3.SuspendLayout()

          TableLayoutPanel3.RowCount += 1

          Dim tb1 As New TextBox()

          Dim tb2 As New TextBox()

          Dim tb3 As New TextBox()

          TableLayoutPanel3.Controls.Add(tb1 , 0, TableLayoutPanel3.RowCount - 1)

          TableLayoutPanel3.Controls.Add(tb2, 1, TableLayoutPanel3.RowCount - 1)

          TableLayoutPanel3.Controls.Add(tb3, 2, TableLayoutPanel3.RowCount - 1)

          TableLayoutPanel3.ResumeLayout()

          tb1.Focus()

 End Sub
回答8

我只是遇到了一个相关的问题(这是我找到此线程的方式),其中我动态添加的行和列样式未生效。 我通常将SuspendLayout()/ ResumeLayout()视为优化,但是在这种情况下,将代码包装在其中可以使行和列的行为正确。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何在Winforms设计器中访问继承的控件(How to access inherited controls in the winforms designer)
    问题 我正在制作一些控件,这些控件必须具有相同的外观和一些共同的行为,尽管它们是为不同种类的输入而设计的。 因此,我做了一个继承自UserControl的BaseClass,而我所有的控件都继承自BaseClass。 但是,如果我在设计器中添加了针对BaseClass的控件(如TableLayoutPanel),则在设计继承的类时将无法访问它们。 我看到了TableLayoutPanel,但是即使他是“受保护的”,我也无法通过设计器修改它或将控件放入其中。 我可以通过代码轻松访问它,但是我不想失去使用设计器的能力。 现在,我只是从BaseClass中删除了所有控件,在每个继承的类中添加了布局和所有公共控件,然后使用引用在BaseClass中对其进行操作。 但这一点都不令我满意。 有没有一种方法可以使设计器与继承的受保护成员控件一起使用? 环境:C#、. NET 3.5,Visual Studio 2008 编辑以回答SLaks的建议。 我尝试设置一个属性,尽管我不习惯使用它们,但它似乎不起作用。 这是我尝试的代码: public partial class UserControl1 : UserControl { public UserControl1() { InitializeComponent(); } public TableLayoutPanel
  • 如何编写自动缩放为系统字体和dpi设置的WinForms代码?(How to write WinForms code that auto-scales to system font and dpi settings?)
    问题 简介:有很多评论说“ WinForms不能很好地自动缩放到DPI /字体设置;切换到WPF”。 但是,我认为它基于.NET 1.1。 看来他们实际上在.NET 2.0中实现自动缩放方面做得很好。 至少根据我们到目前为止的研究和测试。 但是,如果你们当中的某些人知道得更多,我们很乐意听取您的意见。 (请不要打扰我们应该切换到WPF ...这不是当前的选择。) 问题: WinForms中的哪些内容不能正确自动缩放,因此应避免? 程序员在编写WinForms代码时应遵循哪些设计准则,以使其能够很好地自动缩放? 到目前为止,我们已经确定的设计准则: 请参阅下面的社区Wiki答案。 那些不正确或不足吗? 我们还应该采用其他准则吗? 还有其他需要避免的模式吗? 任何其他对此的指导将不胜感激。 回答1 不支持正确缩放的控件: 具有AutoSize = False Label ,并且继承了Font 。 在控件上明确设置Font ,使其在“属性”窗口中以粗体显示。 ListView列的宽度不能缩放。 重写窗体的ScaleControl来代替它。 看到这个答案 SplitContainer的Panel1MinSize , Panel2MinSize和SplitterDistance属性具有MultiLine = True TextBox和Font继承。 在控件上明确设置Font ,使其在“属性
  • 在WinForms应用程序中查找集中控件的首选方法是什么?(What is the preferred way to find focused control in WinForms app?)
    问题 在WinForms中查找当前正在接收用户(键盘)输入的控件的首选/最简单方法是什么? 到目前为止,我已经提出了以下建议: public static Control FindFocusedControl(Control control) { var container = control as ContainerControl; return (null != container ? FindFocusedControl(container.ActiveControl) : control); } 从表单中,可以简单地称为(在.NET 3.5及更高版本中,甚至可以将其定义为表单上的扩展方法)- var focused = FindFocusedControl(this); 这样合适吗 有没有我应该使用的内置方法? 请注意,使用层次结构时,仅对ActiveControl的单个调用是不够的。 想象: Form TableLayoutPanel FlowLayoutPanel TextBox (focused) (formInstance).ActiveControl将返回对TableLayoutPanel的引用,而不是TextBox的引用(因为ActiveControl似乎只返回控件树中的直接活动子级,而我正在寻找叶子控件)。 回答1 如果您已经对Windows
  • WinForms Designer and TableLayoutPanel SmartTag Customization
    I am trying to customize the existing Smart Tag content for a TableLayoutPanel Windows Forms control for use in the Windows Forms designer (I implemented a designer that leverages the WinForms designer features exposed by the System.ComponentModel.Design and System.Windows.Forms.Design namespaces). Whatever approach is offered as a solution, it's got to also work when my control is added to the Visual Studio toolbox and when my control is placed on a WinForm surface in design mode while in the Visual Studio IDE. Here's what I'm trying to do: In design mode, a TableLayoutPanel control instance
  • How to access inherited controls in the winforms designer
    I'm making some controls which all have to share the same look and some common behavior, although they are meant for different kind of inputs. So I made a BaseClass which inherit from UserControl, and all my controls inherit from BaseClass. However, if i add controls for BaseClass in the designer, such as a TableLayoutPanel, i can't access them when I'm designing the inherited classes. I see the TableLayoutPanel, but even though he is "protected", i can't modify it or put controls in it through the designer. I've no trouble accesing it by code, but i don't want to lose the ability to use the
  • Remove Row inside TableLayoutPanel makes a layout problem
    I have a WinForms application that has a TableLayoutPanel; this is the definition code: tableLayoutPanel1 = new TableLayoutPanel(); tableLayoutPanel1.Dock = DockStyle.Fill; tableLayoutPanel1.AutoScroll = true; tableLayoutPanel1.RowCount = users.Count + 1; tableLayoutPanel1.ColumnCount = 1; tableLayoutPanel1.GrowStyle = TableLayoutPanelGrowStyle.FixedSize; tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F)); foreach (String user in users) { tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType.Absolute, 600F)); } tableLayoutPanel1.RowStyles.Add(new RowStyle(SizeType
  • winforms手风琴[关闭](winforms accordion [closed])
    问题 关闭。 此问题不符合堆栈溢出准则。 它当前不接受答案。 想要改善这个问题吗? 更新问题,使它成为Stack Overflow的主题。 6年前关闭。 改善这个问题 有人知道ac#winforms手风琴控制吗? 最好是开源或免费的。 回答1 这是一个使用CheckBox控件的Appearance的基本示例,其中Header的Appearance设置为Button 。 在sourceforge上下载accordion.cs。 演示代码: Accordion acc = new Accordion(); acc.CheckBoxMargin = new Padding(2); acc.ContentMargin = new Padding(15, 5, 15, 5); acc.ContentPadding = new Padding(1); acc.Insets = new Padding(5); acc.ControlBackColor = Color.White; acc.ContentBackColor = Color.CadetBlue; TableLayoutPanel tlp = new TableLayoutPanel { Dock = DockStyle.Fill, Padding = new Padding(5) }; tlp.TabStop = true; tlp
  • 创建可识别DPI的应用程序(Creating a DPI-Aware Application)
    问题 我在C#中有一个表单应用程序。 当我更改监视器的DPI时,所有控件都会移动。 我使用了代码this.AutoScaleMode = AutoScaleMode.Dpi ,但是并不能避免该问题。 有人有主意吗? 回答1 编辑:从.NET 4.7开始,Windows窗体改进了对High DPI的支持。 请在docs.microsoft.com上了解有关此内容的更多信息。它仅适用于Win 10 Creators Update和更高版本,因此根据用户群的不同,可能尚不可行。 困难,但并非不可能。 最好的选择当然是转到WPF,但这可能不可行。 我花了很多时间解决这个问题。 以下是一些规则/准则,可使其在没有FlowLayoutPanel或TableLayoutPanel的情况下正常工作: 始终以默认的96 DPI(100%)编辑/设计您的应用程序。 如果您以120DPI(125%f.ex)进行设计,那么当您回到96 DPI以后再使用它时,它将变得非常糟糕。 我成功使用了AutoScaleMode.Font,但没有尝试太多AutoScaleMode.DPI。 确保在所有容器(窗体,面板,标签页,用户控件等)上使用默认字体大小。 8,25像素。 最好不要对所有容器都在.Designer.cs文件中进行设置,以便它使用容器类中的默认字体。 所有容器必须使用相同的AutoScaleMode
  • What is the preferred way to find focused control in WinForms app?
    What is the preferred/easiest way to find the control that is currently receiving user (keyboard) input in WinForms? So far I have come up with the following: public static Control FindFocusedControl(Control control) { var container = control as ContainerControl; return (null != container ? FindFocusedControl(container.ActiveControl) : control); } From a form, this can be called simply as (in .NET 3.5+ this could even be defined as an extension method on the form) - var focused = FindFocusedControl(this); Is this appropriate? Is there a built-in method that I should be using instead? Note that
  • 使用窗体调整大小调整控件(Resize Controls with Form Resize)
    问题 我已经阅读了几个堆栈溢出问题,但没有找到解决我的问题的有效方法。 每当调整窗体大小时,如何调整控件大小? 我希望它们在表格变大或变小时变大或变小。 在Visual Basic中,使用form.Zoom属性非常容易(当然,它实际上并不需要调整控件的大小,但是可以解决我所需要的内容)。 不幸的是,这在C#winforms中不可用。 这是我没有运气尝试过的其他方法: private void formMain_Resize(object sender, EventArgs e) {/* double scale; this.scaleWidth = (float)this.Width / (float)this.origWidth; this.scaleHeight = (float)this.Height / (float)this.origHeight; if (this.scaleHeight > this.scaleWidth) { scale = this.scaleHeight; } else { scale = this.scaleWidth; } foreach (Control control in this.Controls) { control.Height = (int)(control.Height * this.scaleHeight); control
  • 如何为控件及其子控件暂停绘画?(How do I suspend painting for a control and its children?)
    问题 我有一个控件,我必须对其进行较大的修改。 我想完全避免重绘,而SuspendLayout和ResumeLayout不够。 如何为控件及其子控件暂停绘画? 回答1 在我之前的工作中,我们一直在努力获取丰富的UI应用程序以立即流畅地进行绘制。 我们正在使用标准的.Net控件,自定义控件和devexpress控件。 经过大量的谷歌搜索和反射器使用后,我遇到了WM_SETREDRAW win32消息。 当您更新控件时,这实际上会停止控件图形,并且可以将IIRC应用于父/包含面板。 这是一个非常简单的类,演示如何使用此消息: class DrawingControl { [DllImport("user32.dll")] public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam); private const int WM_SETREDRAW = 11; public static void SuspendDrawing( Control parent ) { SendMessage(parent.Handle, WM_SETREDRAW, false, 0); } public static void ResumeDrawing( Control parent ) {
  • How to disable horizontal scrollbar for table panel in winforms
    Hi I've a tablelayoutpanel and I'm binding controls to it dynamically. When the item count exceeds the height of panel obviously vertical scroll bar appearing there is no problem. But the same time horizontal scroll bar is also appearing even the items width is less than the width of panel. How can i prevent this?
  • Winforms-单击/拖动表单中的任何位置以将其移动,就像在表单标题中单击一样[重复](Winforms - Click/drag anywhere in the form to move it as if clicked in the form caption [duplicate])
    问题 这个问题已经在这里有了答案: 使无边界表格可移动吗? (20个答案) 1年前关闭。 我正在创建一个用于Winforms应用程序的小型模式窗体。 它基本上是一种进度条。 但是我希望用户能够单击表单中的任何位置并将其拖动以在仍显示在桌面上的情况下在桌面上四处移动。 如何实现这种行为? 回答1 Microsoft KB文章320687对此问题有详细的解答。 基本上,当要测试的点位于窗体的客户区域时,您重写WndProc方法以将HTCAPTION返回到WM_NCHITTEST消息-实际上,这是告诉Windows将单击视为与单击时完全相同。表格的标题。 private const int WM_NCHITTEST = 0x84; private const int HTCLIENT = 0x1; private const int HTCAPTION = 0x2; protected override void WndProc(ref Message m) { switch(m.Msg) { case WM_NCHITTEST: base.WndProc(ref m); if ((int)m.Result == HTCLIENT) m.Result = (IntPtr)HTCAPTION; return; } base.WndProc(ref m); } 回答2 这是使用P /
  • ObservableCollection<T> in Winforms and possible alternatives
    Winforms .net 3.5 app. In my app I have a generic class that looks like so: public class FilterItem { public FilterItem() { } public string FilterProperty { get; set; } public bool FilterPropertyChecked { get; set; } public ComparitiveOperator FilterOperator { get; set; } public string FilterValue { get; set; } } and I use it in all of my dialog boxes when I want to implement some sort of filter functionality. So I call the dialog form with a pre-poulated List<FilterItem> passed in the constructor. Now when the dialog loads, it iterates thru each list-item and adds: A checkbox A combobox A
  • 在网格布局中创建动态按钮-创建魔术正方形UI(Create dynamic buttons in a grid layout - Create a magic square UI)
    问题 我应该使用Windows Forms Application在2D中创建一个魔术方块。 它看起来应该像这样: 但是,用户应该能够决定正方形的大小(3x3、5x5、7x7等)。 我已经在控制台应用程序中编写了代码,但是我不知道如何添加2D图形。 有人已经问过这个问题(如何将结果放入GUI中?),答案之一是使用DataGridView ,但是我不确定那不是我要的内容,因为我做不到看起来像图片。 有什么想法或建议吗? 回答1 您可以使用TableLayoutPanel并向面板动态添加按钮。 如果不需要与按钮进行交互,则可以添加Label 。 动态创建正方形: public void CreateSquare(int size) { //Remove previously created controls and free resources foreach (Control item in this.Controls) { this.Controls.Remove(item); item.Dispose(); } //Create TableLayoutPanel var panel = new TableLayoutPanel(); panel.RowCount = size; panel.ColumnCount = size; panel.BackColor = Color
  • 在Windows窗体中显示控件的集合(Displaying a collection of controls in Windows Forms)
    问题 我想显示以下内容:- 每行都与一个进程有关(诸如PID,Parent等信息)。 用户可以选中该checkbox ,然后单击“启动”按钮以获取有关该过程的一些动态详细信息。 问题在于CheckedListBox控件不允许多于一列,而其他控件(如ListView (允许多列))不允许将诸如checkbox控件嵌入到一列中。 我想知道是否有一个控件,该控件将使我拥有一系列自定义控件,其中每个自定义控件都包含一个checkbox ,“ Some Text和“ Some Dynamic Text 。 如何在Windows窗体中实现? 提前致谢。 回答1 您可以使用以下任一选项: DataGridView (示例) 您可以使用DataGridView来显示不同类型的多个列,包括TextBox , Label , CheckBox , ComboBox , Image , Button , Link 。 您还可以通过自定义绘画或添加新的自定义列类型来自定义网格的外观。 用户控件您可以创建包含所需的任何其他控件的复合控件或UserControl并将其用作行模板,然后可以通过在Panel或FlowLayoutPanel中托管该用户控件的多个实例来显示所有行。 TableLayoutPanel (示例) 您可以使用包含多个列和行的TableLayoutPanel。
  • TableLayoutPanel displays vertical scroll
    I have TableLayoutPanel for dynamic creation of controls with AutoScroll = true. It's work fine when I add new controls. But when I remove and all controls are visible, vertical scroll is visible. Some screenshots here: Expected/correct scroll visibility: Incorrect visibility: Any ideas? Update: Here is some code tableLayoutPanel1.SuspendLayout(); tableLayoutPanel1.RowCount = 0; tableLayoutPanel1.RowStyles.Clear(); tableLayoutPanel1.AutoScroll = true; tableLayoutPanel1.Padding = new Padding(0, 0, SystemInformation.VerticalScrollBarWidth, 0); foreach (var item in objects) { tableLayoutPanel1
  • 在“设计”视图中显示以编程方式添加到WinForms应用程序中的控件?(Show controls added programmatically in WinForms app in Design view?)
    问题 使用Visual Studio(可以使用任何版本)时,切换回“设计”视图时是否可以通过编程方式(而不是通过“设计”视图)添加控件? 我已经尝试过一些非常简单的事情: public Form1() { AddCtrl(); InitializeComponent(); AddCtrl(); } private void AddCtrl() { this.SuspendLayout(); this.Controls.Add(new TextBox()); this.ResumeLayout(false); this.PerformLayout(); } ...但无济于事。 回答1 设计人员是否运行我的代码? 当表单在设计器中显示时,设计器反序列化表单代码(Form1.Designer.cs或Form1.cs中的第一类),并创建表单基类的实例,反序列化InitializeComponent并创建您在其中声明的控件您的课程并设置其属性。 因此, Constructor的代码将无法运行。 设计器仅创建表单基类的实例,而不查看表单的构造函数。 设计师如何工作的有趣例子 查看下面的代码,并注意以下问题: 在哪里; s? Form1构造方法Form111111 ? 什么是NotDefinedFunction() ? 我怎么能int i = "xxxxxxxxxx" ? 即使创建此类文件
  • TableLayoutPanel responds very slowly to events
    In my application I really needed to place a lot of controls (label, textbox, domainupdown) in a nice order. So I went ahead and used some nested TableLayoutPanel. The problem now is, this form responds very slow to most of events (resize, maximize, minimize and ...) it takes really up to 5 seconds for controls within the tables to get resized, redrawed to the new size of form. I am putting a finger in my eye now! If this form is that slow on my home PC (i7@4GHz and a good graphic card) what it will do tommorow on the old P4 computer at work? I even tried to use the code below but it does
  • Winforms问题-创建窗口句柄时出错[重复](Winforms issue - Error creating window handle [duplicate])
    问题 这个问题已经在这里有了答案: “创建窗口句柄时出错” (9个答案) 8年前关闭。 我们在Winform应用程序中看到此错误。 任何人都可以帮助您解释为什么会看到此错误,更重要的是如何解决或避免发生此错误。 System.ComponentModel.Win32Exception: Error creating window handle. at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp) at System.Windows.Forms.Control.CreateHandle() at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible) at System.Windows.Forms.Control.CreateControl() at System.Windows.Forms.Control.OnVisibleChanged(EventArgs e) at System.Windows.Forms.ButtonBase.OnVisibleChanged(EventArgs e) 回答1 您是否已运行Process Explorer或Windows Task Manager来查看GDI对象,句柄