【问题标题】:C# NET WinForms Alternative to DataGridView for displaying user controls用于显示用户控件的 C# NET WinForms 替代 DataGridView
【发布时间】:2017-07-23 22:53:47
【问题描述】:

我正在编写一个 C# .NET WinForms 应用程序,我必须在其中创建一个用户控件的新实例,该实例将包含多个控件(TextBox、Button、CheckBox 等)。用户控件必须一次创建一个并堆叠(垂直排列)。

我尝试过的选项:

FlowLayoutPanel 没有可用于跟踪用户单击“添加新项目”按钮时将添加的许多用户控件的索引值。

DataGridView 没有用于容纳用户控件的列类型。虽然 DataGridView 的功能更接近我的需要,但我还没有找到任何代码来添加 UserControl 类型的列。

有什么想法吗?

【问题讨论】:

  • FlowLayoutPanel 没有索引值 那么你添加到 Controls 集合中并可以使用它的索引,只要你不删除它。它当然是完美的控制,完全适合您的情况。但是您需要更清楚地定义您希望如何访问 UC!
  • 模拟 DGV 从来都不是一个非常严重的错误,绘画费用会扼杀程序的性能。请务必提供您自己的自定义单元格类型,教程is here

标签: c# winforms datagridview


【解决方案1】:

也许TableLayoutPanel 是你需要的。

    protected override void OnLoad( EventArgs e )
    {
        var tableLayoutPanel = new TableLayoutPanel
        {
            Dock = DockStyle.Fill,
            AutoScroll = true
        };

        Controls.Add( tableLayoutPanel );

        // To reset row and columns use this

        // Reset row count and styles
        tableLayoutPanel.RowCount = 0;
        tableLayoutPanel.RowStyles.Clear();

        // Reset columns count and styles
        tableLayoutPanel.ColumnCount = 0;
        tableLayoutPanel.ColumnStyles.Clear();

        // For horizontal alignment we need add empty columns to fill space
        // |___emty fill___|Realcoulmn|___empty fill___|
        tableLayoutPanel.ColumnCount = 3;
        tableLayoutPanel.ColumnStyles.Add( new ColumnStyle( SizeType.Percent, 100 ) );  // Fill space
        tableLayoutPanel.ColumnStyles.Add( new ColumnStyle( SizeType.AutoSize ) );      // Real column with controls
        tableLayoutPanel.ColumnStyles.Add( new ColumnStyle( SizeType.Percent, 100 ) );  // Fill space

        tableLayoutPanel.SuspendLayout();

        for ( var i = 0; i < 5; i++ )
        {
            AddControl( tableLayoutPanel, 1 );
        }

        tableLayoutPanel.ResumeLayout( true );
    }

    public void IterateOverControls( TableLayoutPanel table )
    {
        // Iterate over all rows
        for ( var i = 0; i < table.RowCount; i++ )
        {
            var control = table.GetControlFromPosition( 1, i ); // Column 1
        }
    }

    public void AddControl( TableLayoutPanel tableLayoutPanel, int column )
    {
        var btn = new Button { Text = "Hello vertical stack!" };
        btn.Click += button_Click;

        // Add row to tableLayoutPanel and set it style
        tableLayoutPanel.RowCount++;
        tableLayoutPanel.RowStyles.Add( new RowStyle( SizeType.Absolute, btn.Height + 5 ) );

        // Add control to stack
        tableLayoutPanel.Controls.Add( btn, column, tableLayoutPanel.RowCount - 1 );
    }

    private void button_Click( object sender, EventArgs e )
    {
        var btnControl = sender as Control;
        if ( btnControl == null )
            return;

        var tableLayoutPanel = btnControl.Parent as TableLayoutPanel;
        if ( tableLayoutPanel == null )
            return;

        AddControl( tableLayoutPanel, 1 );
    }
}

【讨论】:

  • 谢谢,德米特里。我会试试 TableLayoutPanel。
  • 好的,Dmitry,它可以工作,但是如何通过按钮的 Click() 事件处理程序中的按钮单击来添加新行?我试图用“foreach”来寻找它,但它没有被识别出来。
  • @manicdrummer 现在看示例,我添加了IterateOverControls 方法来迭代列中的控件。我还添加了一个从事件处理程序添加控件和列水平对齐的示例。
  • @manicdrummer 如果解决方案有效,请标记此答案或描述问题一起解决。
猜你喜欢
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-30
  • 1970-01-01
  • 2010-09-07
  • 2021-06-06
相关资源
最近更新 更多