Create a Toolstrip for each Toolstripbutton located on a main Toolstrip - c#

I want to create a Toolstrip and for each ToolStripButton. I also want to create a Toolstrip below the first, in this way each Toolstrip dynamically appear when I click on a ToolStripButton.
I have tried to create the main Toolstrip with Visual Studio designer and for the other toolstrips below I tried to use a customize Toolstrip class. But when I tried to add them:
var cts = new CustomToolStrip();
this.Controls.Add(cts);`
they appeared above of the main Toolstrip.
Here is my CustomToolStrip class:
public class CustomToolStrip : ToolStrip
{
public ToolStripSec()
{
this.GripStyle = ToolStripGripStyle.Hidden;
this.Padding = new Padding(4, 2, 4, 2);
this.AutoSize = true;
this.Dock = DockStyle.Top;
this.Location = new Point(0, 42);
var tspr = new ToolStripProfessionalRenderer();
tspr.RoundedEdges = false;
this.Renderer = tspr;
}
}
Form:
public partial class MainForm : Form
{
public FormAccueil()
{
InitializeComponent(); //this method add the first toolstrip (TSMain)
var r = new ToolStripProfessionalRenderer();
r.RoundedEdges = false;
TSMain.Renderer = r;
var cts = new CustomToolStrip();
this.Controls.Add(cts); // here is the problem
}
}
Result:
http://s16.postimg.org/9kgh0xmh1/Capture.png
Toolstrip 1 and 2 both have the property dock = top.
What can I do to get the Toolstrip 2 below the Toolstrip 1 ?
Could someone guide me please...

Try setting the z-order:
this.Controls.Add(cts);
cts.BringToFront();

Related

Groupbox created in code doesn't dock correctly to parent TableLayoutPanel

In my C# WinForm application I have a tableLayoutPanel with only one row and two columns. The left column contains a TreeView, the right one another tableLayoutPanel which was set to Dock: Fill in the designer. I want to create several GroupBoxes programmatically that should use the full width of this second column also when the form is resized.
In the designer of Visual Studio it looks like this:
But when the application runs, the GroupBoxes don't use the complete width and it looks like this:
I'm using two methods to create the GroupBoxes (you can ignore the int values):
private void addDashboardRow(int i, int s)
{
// Add one row to dashboardTableLayoutPanel
sensorTableLayoutPanel.RowCount++;
// Maybe this one is wrong, but SizeType.AutoSize doesn't work either
sensorTableLayoutPanel.RowStyles.Add(new RowStyle(SizeType.Absolute, 75f));
sensorTableLayoutPanel.Controls.Add(createSensorGroupbox(i, s));
}
private GroupBox createSensorGroupbox(int i, int sen)
{
GroupBox g = new GroupBox();
//g.Width = 500; // I don't want fixed sizes, height of 75px is sufficient
//g.Height = 75;
g.Dock = DockStyle.Fill;
g.Text = "Sensor " + sen.ToString();
// just one label as example...
Label temp = new Label();
temp.Text = "Temperature: ";
temp.Location = new Point(5, 20);
Label tempVal = new Label();
tempVal.Text = "°C";
tempVal.Location = new Point(5, 50);
tempVal.Name = "Sensor" + sen.ToString() + "_temp";
//[... more labels]
g.Controls.Add(temp);
g.Controls.Add(tempVal);
return g;
}
My questions are:
How can I fit the GroupBox into the complete width of the parent container?
How can I delete all rows? E.g. when looking up the sensors during run time all GroupBoxes are dublicated, but everything should be created newly.
Layout of the question: how should I format terms like TableLayoutPanel correctly in this forum? It's my second question here and I haven't found out, yet.
For the second question. Currently I'm using this method that doesn't do what I'm expecting:
private void clearDashboardTable()
{
if (sensorTableLayoutPanel.Controls.Count == sensorList.Count) {
//MessageBox.Show(sensorTableLayoutPanel.Controls.Count.ToString());
foreach (Control con in sensorTableLayoutPanel.Controls)
{
sensorTableLayoutPanel.Controls.Remove(con);
con.Dispose();
}
//sensorTableLayoutPanel.Dispose();
sensorList.Clear();
}
}
I commented out what I've tried so far in the above code or added additional comments. I used this topic to try to understand the basics of dynamic groupbox creation: Add Row Dynamically in TableLayoutPanel
One way to achieve the outcome you describe is to make a custom UserControl containing a docked GroupBox that contains a docked TableLayoutPanel.
To adjust the width when the container changes, attach to the SizeChanged event of the parent.
public partial class CustomGroupBox : UserControl
{
public CustomGroupBox() => InitializeComponent();
protected override void OnHandleCreated(EventArgs e)
{
base.OnHandleCreated(e);
if((Parent != null) &&!DesignMode)
{
Parent.SizeChanged += onParentSizeChanged;
}
}
private void onParentSizeChanged(object? sender, EventArgs e)
{
if(sender is FlowLayoutPanel flowLayoutPanel)
{
Debug.WriteLine($"{flowLayoutPanel.Width}");
Width =
flowLayoutPanel.Width -
SystemInformation.VerticalScrollBarWidth;
}
}
public new string Text
{
get=>groupBox.Text;
set=>groupBox.Text = value;
}
}
Main Form
The main form is laid out similar to your image except to substitute a FlowLayoutPanel on the right side.
Now test it out with this minimal code in the method that loads the Main Form:
public partial class MainForm : Form
{
int _id = 0;
public MainForm()
{
InitializeComponent();
flowLayoutPanel.AutoScroll= true;
for (int i = 0; i < 5; i++)
{
var customGroupBox = new CustomGroupBox
{
Text = $"Sensor {++_id}",
Width = flowLayoutPanel.Width - SystemInformation.VerticalScrollBarWidth,
Padding = new Padding(),
Margin = new Padding(),
};
flowLayoutPanel.Controls.Add(customGroupBox);
}
}
}
Clear
An example of clearing the sensors would be to add a button and set a handler in the same Load method:
buttonClear.Click += (sender, e) => flowLayoutPanel.Controls.Clear();

How to create multiple RichTextBoxes

I need to crate a certain number of RichTextBoxes depending on User Input.
I can create one in visual studio using the toolbox, but how would I go about creating multiple through code?
UPDATE:
This is now my code:
RichTextBox richTextBox = new RichTextBox();
richTextBox.Location = new Point(12, 169);
richTextBox.Width = 62;
richTextBox.Height = 76;
this.Controls.Add(richTextBox);
Nothing happens when I run this
OK. Here is a sample that shows that it works:
void Main()
{
Form f = new Form();
Button b = new Button();
b.Click += (sender, args) =>
{
RichTextBox richTextBox = new RichTextBox
{
Name = "rtbBlahBlah",
Location = new System.Drawing.Point(12, 169),
Width = 62,
Height = 76
};
f.Controls.Add(richTextBox);
};
f.Controls.Add(b);
f.Show();
}
Call this.Refresh() to refresh the Control and re-draw all the children within it.
From the Docs:
Forces the control to invalidate its client area and immediately redraw itself and any child controls.

Forcing the inner part of a form to stay in the same position while changing border style

I have a winform that starts out with a sizable border around it. On the form is a button which, when pressed, changes the form to border style none.
The problem is that then the inner part of the form moves up and to the left slightly. I want to make it that, no matter what border is used, the "inner" part of the form will always stay in the same spot (note: but I do still want the form to be moved around when it has a movable border selected)
Thanks.
The Borderless form moves up and slightly left because thats the location that the form currently has,you need to count for the border.To achieve the result you are after you need to reassign the location property and to do that you need to account for the client size and the whole size(with border),the code i think is simple and it will be self-explanatory i believe:
private void button1_Click(object sender, EventArgs e)
{
var X = (this.Size.Width - this.ClientRectangle.Width) / 2;
var Y = (this.Size.Height - this.ClientRectangle.Height) - X;
Point p = new Point(Location.X + X, Location.Y + Y);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Location = p;
}
Another option is to set the padding on the parent that contains the panel with the border. E.g.
public class Form10 : Form {
Button btn = new Button { Text = "Button", Location = new Point(100, 100) };
Panel border = new Panel { Dock = DockStyle.Fill, BorderStyle = BorderStyle.Fixed3D };
public Form10() {
Controls.Add(border);
border.Controls.Add(btn);
btn.Click += delegate {
if (border.BorderStyle == BorderStyle.Fixed3D) {
border.BorderStyle = BorderStyle.None;
border.Parent.Padding = new Padding(2);
}
else {
border.BorderStyle = BorderStyle.Fixed3D;
border.Parent.Padding = new Padding(0);
}
};
}
}

ComboBoxes won't show up

Why won't the comboboxes show up on the form? (They are invisible)
private ComboBox[] statsValues;
public frmMain()
{
InitializeComponent();
statsValues = new ComboBox[5];
for (byte b = 0; b < statsValues.Length; b++)
{
statsValues[b] = new ComboBox();
statsValues[b].Location = new System.Drawing.Point(300, 300);
statsValues[b].DropDownStyle = ComboBoxStyle.DropDownList;
statsValues[b].Visible = true;
statsValues[b].Enabled = true;
}
}
The controls created dinamically in this way need to be added to the Form controls' collection
this.Controls.AddRange(statsValues);
As a side note, you are creating 5 combox all at the same position. When you show them on your form you won't be able to see all of them, only the last one on the top of the other fours

Get real-time scrolling without AutoScroll

After asking this: Prevent AutoScroll when contained Control gets focus I've found a way to have a scrollbar without the AutoScroll (using a derived class which can access the VScroll property). However - it's not in real-time. i.e. Only when the user is done scrolling does the Control actually get scrolled. (as opposed to a Panel with AutoScroll = true.) So how do I get it to scroll in real-time?
My code:
using System.Drawing;
using System.Windows.Forms;
namespace test
{
public partial class Form1 : Form
{
MyPanel panel = new MyPanel
{
//AutoScroll = true,
Size = new Size(200, 200),
Location = new Point(0, 30),
BackColor = Color.Green
};
Button b1 = new Button
{
Location = new Point(100, 100),
Size = new Size(50, 150),
BackColor = Color.Black
};
Button b2 = new Button();
public Form1()
{
InitializeComponent();
panel.Controls.Add(b1);
Controls.Add(panel);
Controls.Add(b2);
Shown += new System.EventHandler(Form1_Shown);
}
void Form1_Shown(object sender, System.EventArgs e)
{
panel.VerticalScroll.Visible = true;
panel.SetV();
}
}
class MyPanel : Panel
{
public void SetV() { VScroll = true; }
}
}
As in the comment:
You'll need to override the panel's OnScroll() method and call
SetDisplayRectLocation(0, -se.NewValue).
That's the answer to this question.
However, I've found that I can't have both scrollbars simultaneously. Or at least - I haven't found a way to do it.

Categories

Resources