动态创建User Control时控件间间隙的消除方法咨询
问题:消除UserControl排列时的异常间隙
我需要动态创建数量可变的User Control展示元素,单个Station控件显示正常,但将4个Station控件排列成正方形时,即便把Margin和Padding都设为0,控件之间还是有无法消除的间隙。调整Location属性也没解决,求消除间隙的方法。
Station控件代码
using System.Drawing; using System.Windows.Forms; namespace NewOPCMotion.CustomComponents { public partial class Station : UserControl { private int _StationNumber; private int _StationPosition; public Station() { InitializeComponent(); // 基于lb_Station设置所有尺寸 lb_StnNo.Location = new Point(0, 0); lb_StnNo.Size = new Size(Constants.STATION_LB_WIDTH, Constants.STATION_LB_HEIGHT); // 将DPS居中在lb_Station内 DPS.Location = new Point((lb_StnNo.Size.Width - DPS.Size.Width) / 2, (lb_StnNo.Size.Height - DPS.Height) / 2); Motor.Location = new Point((lb_StnNo.Size.Width - Motor.Size.Width) / 2, lb_StnNo.Size.Height); // SV紧贴lb_Station右侧 SV.Location = new Point(lb_StnNo.Width + 1, 1); // S1/S2位置 S1.Location = new Point(lb_StnNo.Left + Constants.SENSOR_OFFSET, lb_StnNo.Size.Height - (S2.Height + 1)); S2.Location = new Point(lb_StnNo.Right - S2.Width - Constants.SENSOR_OFFSET, lb_StnNo.Size.Height - (S2.Height + 1)); // 面板尺寸 pnl_Station.Size = new Size(SV.Right, Motor.Bottom); // 控件尺寸 Size = new Size(pnl_Station.Size.Width, pnl_Station.Size.Height); //Padding = new Padding(0); //Margin = new Padding(0); } public void SetLocation(int X, int Y) { pnl_Station.Location = new Point(X, Y); } // 属性 public int StationNumber { get { return _StationNumber; } set { _StationNumber = value; lb_StnNo.Text = "Stn " + StationNumber.ToString(); } } public int StationPosition { get { return _StationPosition; } // 获取方法 set { _StationPosition = value; } // 设置方法 } } }
ProcessModule控件代码
using System.Collections.Generic; using System.ComponentModel; using System.Drawing; using System.Data; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; namespace NewOPCMotion.CustomComponents { public partial class ProcessModule : UserControl { private Station[] Stations; private Panel ModulePanel; public ProcessModule() { InitializeComponent(); Stations = new Station[4]; ModulePanel = pnl_Module; for (int i = 0; i < 4; i++) { Stations[i] = new Station(); Stations[i].StationPosition = i; Stations[i].Margin = new Padding(0); Stations[i].Padding = new Padding(0); ModulePanel.Controls.Add(Stations[i]); } // 排列W、X、Y、Z四个Station ModulePanel.Controls[0].Location = new Point(0, 0); ModulePanel.Controls[1].Location = new Point(ModulePanel.Controls[0].Right, 0); ModulePanel.Controls[2].Location = new Point(ModulePanel.Controls[0].Right, ModulePanel.Controls[0].Bottom); ModulePanel.Controls[3].Location = new Point(0, ModulePanel.Controls[0].Bottom); // Size = new Size(Constants.STATION_WIDTH * 2, Constants.STATION_HEIGHT * 2); } public void SetStationNumbers(int ModuleNumber) { for (int i = 0; i < 4; i++) { // TODO: 设置工位编号 Stations[i].StationNumber = i; } } public void SetLocation(int X, int Y) { ModulePanel.Location = new Point(X, Y); } } }
解决方法
1. 修复Station控件的尺寸偏移问题
你的Station构造函数里,多个控件的位置设置用了+1的硬编码偏移,这会导致整个控件的尺寸被额外撑开,直接产生间隙。修改这些位置计算:
// SV位置修改 SV.Location = new Point(lb_StnNo.Width, 0); // S1/S2位置修改 S1.Location = new Point(lb_StnNo.Left + Constants.SENSOR_OFFSET, lb_StnNo.Size.Height - S2.Height); S2.Location = new Point(lb_StnNo.Right - S2.Width - Constants.SENSOR_OFFSET, lb_StnNo.Size.Height - S2.Height);
2. 彻底清零Station的内外边距
在Station构造函数中取消注释并启用Padding和Margin的设置,同时确保自动尺寸功能关闭:
// 在Station构造函数中添加 Padding = new Padding(0); Margin = new Padding(0); AutoSize = false;
3. 精确计算排列位置
不要依赖控件的Right/Bottom属性计算位置,直接用固定的Station尺寸值来定位,避免控件尺寸计算误差:
// 在ProcessModule构造函数中修改位置设置 int stationWidth = Stations[0].Width; int stationHeight = Stations[0].Height; ModulePanel.Controls[0].Location = new Point(0, 0); ModulePanel.Controls[1].Location = new Point(stationWidth, 0); ModulePanel.Controls[2].Location = new Point(stationWidth, stationHeight); ModulePanel.Controls[3].Location = new Point(0, stationHeight);
4. 检查容器Panel的属性
确保pnl_Module的Padding也设置为new Padding(0),并且AutoScroll属性设为false,避免滚动条或容器内边距导致的布局偏移。
内容的提问来源于stack exchange,提问作者mygrandclarity
相关产品推荐
相关产品推荐

