Create spacing between checkboxes - c#

I'm auto generating checkboxes and putting them into a panel,but when I do that, they all appear at the same point. I can manually move them apart, but this could cause problems down the line. Is there a way to get them to automatically align under each other.
Here's my code:
foreach (Category i in DesktopApp.getBaseCat())
{
checkBox = new CatBox();
checkBox.setCat(i);
checkBox.Text = i.ToString(); // puts the name of the category in the text field
checkBox.Click += new EventHandler(simpleCatBox_Click);
this.categoryPanel.Controls.Add(checkBox); // adds it to the panel
step++; // increments step
}

Give the checkbox a margin (10px in this example)
checkBox.Margin = new Thinkness(10);
Or, if you want different margins
checkBox.Margin = new Thickness(left,top,right,bottom);

Related

C# - Dynamically drawing a table and contents results in extra row

I am dynimically populating a panel with a table and adding some rows, columns, images and labes into the table based on the number of attached monitors. Each time the 'Monitors' panel is opened up, the dynimically added controls are removed and then re-added again in case any settings have been changed since it was last opened. When the panel is loaded for the first time, this is how it appears:
This is just how I want it to display. Both monitors detected and correct resolutions specified. Now, when the the Monitors panel is navigated away from, then switched back to (triggering the table contents to be removed and re-added), it displays with an extra row and old label like so:
No matter how many times the panel is navigated away from and back to, it always displays correctly the first time it's opened, then incorrectly any time after. Here is my code for populating the panel:
public void monitorPanel_Paint()
{
// Remove existing monitor pictures
foreach (Control item in monitorLayoutPanel.Controls.OfType<PictureBox>())
{
monitorLayoutPanel.Controls.Remove(item);
item.Dispose();
}
// Remove existing monitor labels
foreach (Control item in monitorLayoutPanel.Controls.OfType<Label>())
{
monitorLayoutPanel.Controls.Remove(item);
item.Dispose();
}
// Get number of attached monitors
int screens = Screen.AllScreens.Count();
// Auto add a table to nest the monitor images and labels
this.monitorLayoutPanel.Refresh();
this.monitorLayoutPanel.ColumnStyles.Clear();
this.monitorLayoutPanel.RowStyles.Clear();
this.monitorLayoutPanel.ColumnCount = screens;
this.monitorLayoutPanel.RowCount = 2;
this.monitorLayoutPanel.AutoSize = true;
int z = 0;
foreach (var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))
{
var percent = 100f / screens;
this.monitorLayoutPanel.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, percent));
PictureBox monitor = new PictureBox
{
Name = "MonitorPic" + z,
Size = new Size(95, 75),
BackgroundImageLayout = ImageLayout.Stretch,
BackgroundImage = Properties.Resources.display_enabled,
Anchor = System.Windows.Forms.AnchorStyles.None,
};
Label resolution = new Label
{
Name = "MonitorLabel" + z,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10),
ForeColor = Color.Black,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height,
Anchor = System.Windows.Forms.AnchorStyles.None,
};
this.monitorLayoutPanel.Controls.Add(monitor, z, 0);
this.monitorLayoutPanel.Controls.Add(resolution, z, 1);
z++;
}
}
I am surprised it isn't throwing an exception when you remove the controls from the Controls collection while enumerating it. It's worth checking if that is causing the enumeration to get clobbered and causing you to skip removing some of the controls. If that is the case, the solutions is capture a List<Control> of controls to remove while enumerating, then remove them all after enumerating it:
List<Control> controlsToRemove = new List<Control>();
foreach (Control item in monitorLayoutPanel.Controls.OfType<PictureBox>()) {
controlsToRemove.Add(item);
}
foreach (Control item in monitorLayoutPanel.Controls.OfType<Label>()) {
controlsToRemove.Add(item);
}
foreach (Control item in controlsToRemove) {
monitorLayoutPanel.Controls.Remove(item);
item.Dispose();
}

devExpress, how to dock gridView to the panel and remove 'drag column header'?

I cannot dock fill gridView to the panel in DevExpress Visual Studio 2010, I cannot remove "drag column header..." as well, both are visible on the screenshot.
Can somebody help me with those issue?!
part of the code:`EntityConnection entityConn = new EntityConnection(Utility.GetEntityConnection("ViEFConn"));
List<Object> myList = new List<Object>();
//GridControl gridcon = new GridControl();
using (ViEFConn dbF = new ViEFConn(entityConn))
{
// LINQ join query
var query = from f in db.Fields
join t in db.Types
on f.TYPE_ID
equals t.TYPE_ID
where (f.ASS_TYPE == _assType)
select new
{
f.NAME,
f.FIELD ,
t.DATA,
f.TEXT,
};
// add linq query to the list
myList.AddRange(query);
// bind data source of grid control to the list
AssignmentDetailsGridControl.DataSource = myList;
gridView1.OptionsBehavior.Editable = true;
SaveButton.Enabled = true;
SaveCloseButton.Enabled = true;
AssignmentDetailsGridControl.Dock = DockStyle.Fill;
gridView1.OptionsCustomization.AllowColumnMoving = false;
gridView1.OptionsView.ShowGroupPanel = false; `
To dock your grid you need to set
GridControl.Dock = DockStyleFill
Note: it is property of GridControl, not GridView.
It is not quite clear what do you mean by remove "drag column header...".
If you want to disable dragging columns you need to set property
GridView.OptionsCustomization.AllowColumnMoving = false
If you want to disable group panel (marked by arrow on your screenshot) you need to set
GridView.OptionsView.ShowGroupPanel = false
You can hide the Grouppanel with
gridview1.optionsview.showgrouppanel = false;
For remove the right empty area you have to set
dockstyle = fill
or you can place DevExpress LayoutControl at first. Set this to docktype=fill and place the grid on the layout control (thats recommended by DevExpress!).
At least make sure you havent place an emptyspaceitem at the right sight.

Dynamically added labels disappear in runtime

I add labels to my form programmatically, but they disappear, except last one. I'm sure that given location to them is appropriate. But when the second label appears, first disappears, or when third label appears, second disappears.
Here is my code:
Label[] lenlab = new Label[255];
Label lab = new Label();
lab.Font = new Font("Microsoft Sans Serif", 10, FontStyle.Bold);
lab.ForeColor = Color.White;
lab.BackColor = Color.Transparent;
lab.AutoSize = true;
lenlab[1] = lab;
lenlab[1].Location = new Point(50, panel1.Location.Y + panel1.Height + 20);
lenlab[1].Text = c[1];
this.Controls.Add(lenlab[1]);
for (int i = 2; i < c.Count; i++)
{
lenlab[i] = lab;
lenlab[i].Location = new Point(lenlab[i - 1].Location.X + lenlab[i -1].Width + 40, lenlab[i - 1].Location.Y);
lenlab[i].Text = " + " + c[i];
this.Controls.Add(lenlab[i]);
}
This line is causing every position in your array to have a reference to the same Label you created originally, outside the loop, which means all you're doing is changing the position and text of the same Label inside your loop.
lenlab[i] = lab;
The behavior you're seeing is due to the fact that you can only add a particular control to this.Controls once, so the effect is that you see the same label changing position.
Here's the portion of the Add() method that checks whether the control you're adding already has a parent, and if it does, then it removes it from it's current parent before adding it to the new one. So every time you call this.Controls.Add() with the same Label, it removes it from the Form and then adds it again.
// Remove the new control from its old parent (if any)
if (value.parent != null) {
value.parent.Controls.Remove(value);
}
Instead, create a new Label inside your for loop:
lenlab[i] = new Label();
There are controls that can help you layout controls without the need to calculate a new position each time. In particular, read up on the FlowLayoutPanel and TableLayoutPanel classes.
What you are doing there is basically create one Label, change it several times, and attach it several times to the page. What you end up having on the page is the last version of the Label being added once, which is the expected behavior.
If you want to add several labels, you need to new each of them.

Can StatusStrip automatically change its height depending on its items' size?

I've got a statusstrip with a number of items. One of them is a ToolStripStatusLabel with Spring = True.
When the text of the label is too long, one can't see it.
Is it possible to make the statusstrip become higher and show whole text in multiline?
This is an interesting problem....I tried a couple of things but no success...basicall the ToolStripStatusLabel is very limited in capability.
I ended up trying a hack that gives the result you want but am not sure even I would recommend this unless of course this is absolutely necessary...
Here's what I have got...
In the properties of your StatusStrip set AutoSize = false, this is to allow the StatusStrip to be resized to accommodate multiple lines. I am assuming statusStrip called ststusStrip1 containing label called toolStripStatusLabel1.
At form Level declare a variable of TextBox type:
TextBox txtDummy = new TextBox();
At Form Load set some of its properties:
txtDummy.Multiline = true;
txtDummy.WordWrap = true;
txtDummy.Font = toolStripStatusLabel1.Font;//Same font as Label
Handle the paint event of the toolStripStatusLabel1
private void toolStripStatusLabel1_Paint(object sender, PaintEventArgs e)
{
String textToPaint = toolStripStatusLabel1.Tag.ToString(); //We take the string to print from Tag
SizeF stringSize = e.Graphics.MeasureString(textToPaint, toolStripStatusLabel1.Font);
if (stringSize.Width > toolStripStatusLabel1.Width)//If the size is large we need to find out how many lines it will take
{
//We use a textBox to find out the number of lines this text should be broken into
txtDummy.Width = toolStripStatusLabel1.Width - 10;
txtDummy.Text = textToPaint;
int linesRequired = txtDummy.GetLineFromCharIndex(textToPaint.Length - 1) + 1;
statusStrip1.Height =((int)stringSize.Height * linesRequired) + 5;
toolStripStatusLabel1.Text = "";
e.Graphics.DrawString(textToPaint, toolStripStatusLabel1.Font, new SolidBrush( toolStripStatusLabel1.ForeColor), new RectangleF( new PointF(0, 0), new SizeF(toolStripStatusLabel1.Width, toolStripStatusLabel1.Height)));
}
else
{
toolStripStatusLabel1.Text = textToPaint;
}
}
IMP: Do not assign the text property of your label instead put it in Tag we would use it from Tag
toolStripStatusLabel1.Tag = "My very long String";

LayoutGrid SetRow and SetColumn not working as intended

I have code that creates a button for each object in a list. When each object is created it is given a name that corresponds to the row and column (i.e. name = row1col2). Each button is generated dynamically, added to the grid and then the row/column are set. At a later time I need to gather the "selected" button data so I can perform actions on the data they represent. When I attempt to get the control data from the buttons everything is fine, except for the grid row/column data. It remains the same for all of the selected rows and columns in a grid.
Creating buttons:
for (int i = 1; i < row.StackCount+1; i++)
{
//create button for the column
stackButton = new Button();
stackButton.Height = ((newRow.Height - 2));
stackButton.Width = ((newRow.Width / row.StackCount) - 2);
stackButton.Background = new SolidColorBrush(Colors.White);
//add the button border
stackButton.BorderBrush = new SolidColorBrush(Colors.Black);
stackButton.BorderThickness = new Thickness(1);
stackButton.Style = Application.Current.Resources["flatButton"] as Style;
//add the button name
stackButton.Name = "Row" + row.LineNumber + "Col" + (i - 1).ToString();
//add the event handler to the button
stackButton.Click += new RoutedEventHandler(stackButton_Click);
//add a new column
newRow.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(newRow.Width, GridUnitType.Star) });
//put the button into the grid
newRow.Children.Add(stackButton);
Grid.SetRow(stackButton, 0);
Grid.SetColumn(stackButton, i-1);
}
Getting the Button data back
g = (Grid)b.Child;
foreach (Button currentButton in g.Children)
{
if (((SolidColorBrush)currentButton.Background).Color == Colors.Gray)
{
//create a stack object
buttonData.StartDate = DateTime.Now;
buttonData.LotNumber = LotDisplay.Text;
buttonData.RoomID = SilverGlobals.CurrentRoom.RoomID;
buttonData.RoomCol = Grid.GetColumn(currentButton);
buttonData.RoomRow = Grid.GetRow(currentButton);
buttonData.TrayCount = int.Parse(currentButton.Content.ToString());
buttonData.Status = 0;
//add stack object to list of stack objects
stacks.Add(buttonData);
}
}
I know this must be something small I am missing. Anyone got any ideas?
Although the comment in your second section of code says:
//create a stack object
you don't actually create a new stack object so it is simply overwriting the single instance of buttonData on each iteration. The values for row and column that you see at the end are the last iteration's values.
The net effect is that stacks is a collection of all the same instance of an object instead of a collection of separate instances.
This is just a shot in the dark, but based on this question and this question, it might be that you need to set the Row and Column properties before you add the button to its parent - something like this:
//put the button into the grid
Grid.SetRow(stackButton, 0);
Grid.SetColumn(stackButton, i-1);
newRow.Children.Add(stackButton);

Categories