C# 在面板内的列中动态创建控件
我有一个面板,可以在其中创建标签和数字向上向下字段,如下所示:C# 在面板内的列中动态创建控件,c#,winforms,C#,Winforms,我有一个面板,可以在其中创建标签和数字向上向下字段,如下所示: List<string> Labels = new List<string>(); public List<Label> DeliveryBreakdownLabelsModel = new List<Label>(); public List<NumericUpDown> DeliveryBreakdownNumericUp
List<string> Labels = new List<string>();
public List<Label> DeliveryBreakdownLabelsModel = new List<Label>();
public List<NumericUpDown> DeliveryBreakdownNumericUpDownModel = new List<NumericUpDown>();
private void SetDeliveryBreakdownAmountForm_Load(object sender, EventArgs e)
{
var rModel = //List data from database
AddRow(rModel);
Arrange();
}
private void AddRow(IList<DeliveryBreakdownGetViewModel> rModel)
{
for (int i = 0; i < rModel.Count; i++)
{
Labels.Add(rModel[i].DesignGroupName);
var label = new Label
{
AutoSize = true, // make sure to enable AutoSize
Name = "label" + Labels.Count,
Text = rModel[i].DesignGroupName,
Location = new Point(12, YPos)
};
this.Controls.Add(label);
pnlDeliveryBreakdown.Controls.Add(label);
DeliveryBreakdownLabelsModel.Add(label);
var numericUpDown = new NumericUpDown
{
Name = "numericUpDown" + Labels.Count,
Text = rModel[i].ContractedAmount.ToString(),
Location = new Point(12, YPos),
Size = new Size(60, 19),
DecimalPlaces = 2,
Maximum = decimal.MaxValue
};
this.Controls.Add(numericUpDown);
this.Controls.Add(numericUpDown);
pnlDeliveryBreakdown.Controls.Add(numericUpDown);
DeliveryBreakdownNumericUpDownModel.Add(numericUpDown);
YPos += 25;
}
}
void Arrange()
{
// Determine the widest label sized by the AutoSize
var maxLabelX = 0;
for (int i = 0; i < Labels.Count; i++)
{
maxLabelX = Math.Max(maxLabelX, DeliveryBreakdownLabelsModel[i].Location.X + DeliveryBreakdownLabelsModel[i].Size.Width);
}
// Move all the text boxes a little to the right of the widest label
var maxNumericX = 0;
for (int i = 0; i < Labels.Count; i++)
{
maxNumericX = Math.Max(maxNumericX, DeliveryBreakdownNumericUpDownModel[i].Location.X + DeliveryBreakdownNumericUpDownModel[i].Size.Width);
DeliveryBreakdownNumericUpDownModel[i].Location = new Point(maxLabelX + 10, DeliveryBreakdownNumericUpDownModel[i].Location.Y);
}
//Set total wi
this.Width = maxNumericX + maxLabelX + 60;
}
列表标签=新列表();
public List DeliveryBreakdownLabelsModel=new List();
public List DeliveryBreakdownNumericUpDownModel=新列表();
私有void SetDeliveryBreakdownAmountForm_加载(对象发送方,事件参数e)
{
var rModel=//列出数据库中的数据
AddRow(rModel);
排列();
}
私有void AddRow(IList rModel)
{
for(int i=0;i
所以它看起来像:
我的问题是,如何修改代码以创建多个列。我想这样做,因为有时我可以有很多数据,所以只有在垂直显示可能是一个问题,在未来。预期结果:即
我建议使用带有
用户控件的TableLayoutPanel
,该控件只包含一个标签和一个数字框
即使在设计师中,这看起来也很整洁
您只需从用户控件的数字框中公开所需的属性
在上面的示例中,我使用以下代码:
// Fixed height user control
// Some code taken from: https://stackoverflow.com/a/4388922/380384
[Designer(typeof(MyControlDesigner))]
public partial class LabelNumeric : UserControl
{
public LabelNumeric()
{
InitializeComponent();
}
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, width, 24, specified);
}
[DefaultValue("Label")]
public string Caption
{
get => label1.Text;
set => label1.Text = value;
}
[DefaultValue(0)]
public decimal Value
{
get => numericUpDown1.Value;
set => numericUpDown1.Value =value;
}
[DefaultValue(0)]
public int DecimalPlaces
{
get => numericUpDown1.DecimalPlaces;
set => numericUpDown1.DecimalPlaces = value;
}
[DefaultValue(100)]
public decimal MaxValue
{
get => numericUpDown1.Maximum;
}
[DefaultValue(0)]
public decimal MinValue
{
get => numericUpDown1.Minimum;
}
}
internal class MyControlDesigner : ControlDesigner
{
MyControlDesigner()
{
base.AutoResizeHandles = true;
}
public override SelectionRules SelectionRules
{
get
{
return SelectionRules.LeftSizeable | SelectionRules.RightSizeable | SelectionRules.Moveable;
}
}
}
您可以从tableLayoutPanel1.controls
属性访问所有控件,并检查它们在表中的位置,如下所示:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
foreach (var item in tableLayoutPanel1.Controls.OfType<LabelNumeric>())
{
var pos = tableLayoutPanel1.GetCellPosition(item);
item.Caption = $"Row{pos.Row}Col{pos.Column}";
}
}
}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
}
受保护的覆盖无效加载(事件参数e)
{
基础荷载(e);
foreach(tableLayoutPanel1.Controls.OfType()中的变量项)
{
var pos=表格布局面板1.GetCellPosition(项目);
item.Caption=$“行{pos.Row}列{pos.Column}”;
}
}
}
因此,在运行时,它如下所示:
诀窍是在底部增加一行自动调整大小,包含控件的所有其他行的固定高度为24pt
我建议使用TableLayoutPanel
和UserControl
,该控件正好包含一个标签和一个数字框
即使在设计师中,这看起来也很整洁
您只需从用户控件的数字框中公开所需的属性
在上面的示例中,我使用以下代码:
// Fixed height user control
// Some code taken from: https://stackoverflow.com/a/4388922/380384
[Designer(typeof(MyControlDesigner))]
public partial class LabelNumeric : UserControl
{
public LabelNumeric()
{
InitializeComponent();
}
protected override void SetBoundsCore(int x, int y, int width, int height, BoundsSpecified specified)
{
base.SetBoundsCore(x, y, width, 24, specified);
}
[DefaultValue("Label")]
public string Caption
{
get => label1.Text;
set => label1.Text = value;
}
[DefaultValue(0)]
public decimal Value
{
get => numericUpDown1.Value;
set => numericUpDown1.Value =value;
}
[DefaultValue(0)]
public int DecimalPlaces
{
get => numericUpDown1.DecimalPlaces;
set => numericUpDown1.DecimalPlaces = value;
}
[DefaultValue(100)]
public decimal MaxValue
{
get => numericUpDown1.Maximum;
}
[DefaultValue(0)]
public decimal MinValue
{
get => numericUpDown1.Minimum;
}
}
internal class MyControlDesigner : ControlDesigner
{
MyControlDesigner()
{
base.AutoResizeHandles = true;
}
public override SelectionRules SelectionRules
{
get
{
return SelectionRules.LeftSizeable | SelectionRules.RightSizeable | SelectionRules.Moveable;
}
}
}
您可以从tableLayoutPanel1.controls
属性访问所有控件,并检查它们在表中的位置,如下所示:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
foreach (var item in tableLayoutPanel1.Controls.OfType<LabelNumeric>())
{
var pos = tableLayoutPanel1.GetCellPosition(item);
item.Caption = $"Row{pos.Row}Col{pos.Column}";
}
}
}
公共部分类表单1:表单
{
公共表格1()
{
初始化组件();
}
受保护的覆盖无效加载(事件参数e)
{
基础荷载(e);
foreach(tableLayoutPanel1.Controls.OfType()中的变量项)
{
var pos=表格布局面板1.GetCellPosition(项目);
item.Caption=$“行{pos.Row}列{pos.Column}”;
}
}
}
因此,在运行时,它如下所示:
诀窍是在底部增加一行自动调整大小,并且包含控件的所有其他行的固定高度为24pt
请参见此->位置=新点(12,YPos),当YPos不断变化时,您总是将X指定给12。这就像垂直填充。您需要改变这两种方式才能得到从左到右的填充。为什么不使用TableLayoutPanel
?如果我使用TableLayoutPanel
如何将一个在右侧,另一个在左侧,依此类推@ja72@Leon-您的意思是如何在同一单元格中包含标签和数字框?我的答案是使用一列作为标签,一列作为上下框,或者创建一个包含标签和上下框的UserControl
。另外,关于如何使UserControl
固定高度,使其感觉像一个文本框。请参见此->位置=新点(12,YPos),您始终是