I have a checkedListBox in a TabControl
What I want is to create a label and NumericUpDown dynamically, when User check an item of checkedListBox it will show the new label and NumericUpDown
Then , when it Unchecked this item ,The numericUpDown will be clear (empty).
Conclusion: As many checked items , as many w've create labels and NumericUpDowns.
Please, how will I do that ??
For each checkbox item in your checkedListBox in properties switch to events and create subscriber checkBoxName_CheckStateChanged for event CheckStateChanged.
The code in the sucriber can be like this:
private void checkBox1_CheckStateChanged(object sender, EventArgs e)
{
var source = sender as CheckBox;
if (source.Checked == true)
{
this.numericUpDown1.Text = "TextWhenChecked";
this.labelAtTheNumericUpDown.Text = "TextWhenChecked";
}
else
{
this.numericUpDown1.Text = "TextWhenUnchecked";
this.label1.Text = "TextWhenUnchecked";
}
}
You fill the strings as you want. These are only examples.
To have only checkBox checked at a time look at here: https://stackoverflow.com/a/24693858/6650581.
What you need to do is creating Label and NumericUpDown manually and show it by adding to Controls collection. A TableLayoutPanel can help you arranging controls without setting Size and calculate Location manually.
Here is an example:
public class MainForm : Form
{
private CheckedListBox checkedListBox;
private TableLayoutPanel tableLayoutPanel;
public MainForm()
{
InitializeComponent();
//Fill checkedListBox and create controls
for( int i = 0; i <= 5; i++ )
{
checkedListBox.Items.Add( i.ToString() );
Label lbl = new Label()
{
Name = "lbl" + i,
Text = "Label " + i,
Visible = false
};
NumericUpDown num = new NumericUpDown()
{
Name = "num" + i,
Value = i,
Visible = false
};
tableLayoutPanel.Controls.Add( lbl, 0, i );
tableLayoutPanel.Controls.Add( num, 1, i );
}
}
private void checkedListBox_ItemCheck( object sender, ItemCheckEventArgs e )
{
if( e.NewValue == CheckState.Checked )
{
tableLayoutPanel.Controls["lbl" + e.Index].Visible = true;
tableLayoutPanel.Controls["num" + e.Index].Visible = true;
}
else
{
tableLayoutPanel.Controls["lbl" + e.Index].Visible = false;
((NumericUpDown)tableLayoutPanel.Controls["num" + e.Index]).Value = 0M;
}
}
private void InitializeComponent()
{
this.checkedListBox = new System.Windows.Forms.CheckedListBox();
this.tableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
this.SuspendLayout();
//
// checkedListBox
//
this.checkedListBox.Location = new System.Drawing.Point(8, 8);
this.checkedListBox.Name = "checkedListBox";
this.checkedListBox.Size = new System.Drawing.Size(200, 100);
this.checkedListBox.TabIndex = 1;
this.checkedListBox.ItemCheck += new System.Windows.Forms.ItemCheckEventHandler(this.checkedListBox_ItemCheck);
//
// tableLayoutPanel
//
this.tableLayoutPanel.AutoScroll = true;
this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 50F));
this.tableLayoutPanel.Location = new System.Drawing.Point(8, 112);
this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.Size = new System.Drawing.Size(200, 100);
this.tableLayoutPanel.TabIndex = 2;
//
// MainForm
//
this.ClientSize = new System.Drawing.Size(223, 227);
this.Controls.Add(this.tableLayoutPanel);
this.Controls.Add(this.checkedListBox);
this.Name = "MainForm";
this.ResumeLayout(false);
}
}
Related
I have a split container panel in GUI Form.When a button is clicked in left panel,it pulls out information along with multiple checkboxes on dynamically created panels on the right panel using a loop.Each panel on the right side can have multiple checkboxes based on some condition.For example, the first panel has one checkbox and the second panel below the first has got 8 checkboxes in the same row.When one of the checkboxes in second panel is clicked, I have to get the index of the that panel to do some manipulation. Tab index does not help me to get one as each panel can have any number of checkboxes.I spent a day to get around the problem with no luck. Your help will be much appreciated. I have posted the code below.
for (int j = 0; j < numOfSensors.Count; j++)
{
sensorpanel = new Panel();
sensorpanel.Size = new Size(800, 60);
sensorpanel.Location = new Point(0, Y);
sensorpanel.BackColor = Color.LightGray;
sensorpanel.Paint += new PaintEventHandler(panel_Paint);
Button sensor = new Button();
sensor.Size = new Size(200, 50);
sensor.Location = new Point(1, 1);
sensor.FlatStyle = FlatStyle.Flat;
sensor.FlatAppearance.BorderColor = Color.LightGray;
String sensorType = "Occupancy";
sensor.TextAlign = ContentAlignment.MiddleLeft;
sensor.BackColor = Color.LightGray;
sensor.ForeColor = Color.Black;
sensorpanel.Controls.Add(sensor);
if (sensorType.Equals("Occupancy"))
{
CheckBox cb = new CheckBox();
cb.Location = new Point(380, 15);
cb.Size = new Size(20, 17);
cb.Checked = checkBox(j,0);
cb.Text = "Occupancy";
checksensorbuttons.Add(cb);
cb.CheckedChanged += new EventHandler(cb_CheckChanged);
sensorpanel.Controls.Add(cb);
}
else if (sensorType.Equals("Multi-input:Digital"))
{
int xLoc = 210;
int yLoc = 15;
for (int k = 16; k <32; k+=2)
{
CheckBox cb = new CheckBox();
cb.Location = new Point(xLoc, yLoc);
cb.Size = new Size(20, 17);
cb.Checked = checkBox(j,k);
cb.Text = "Multi-input";
cb.CheckedChanged += new EventHandler(cb_CheckChanged);
sensorpanel.Controls.Add(cb);
xLoc += 30;
}
splitContainer.panel2.Controls.Add(sensorpanel);
}
//checkedchanged eventhandler
private void cb_CheckChanged(object sender, EventArgs e)
{
CheckBox checkbox = (CheckBox)sender;
if (checkbox.Text.Equals("Occupancy"))
{
// How to get the index of the panel when a checkbox in corresponding panel is checked?
if (checkbox.Checked == true)
{
//some manipulation
}
else
{
//some manipulation
}
}
else if (checkbox.Text.Equals("Multi-input"))
{
//get index of the panel where one of the checkboxes are clicked
if (checkbox.Checked == true)
{
//do some manipulation
}
else
{
//do some manipulation
}
}
There are multiple ways
Use Name property of the checkbox. When the checkbox is created assign it a logical name which makes it easier to identify it. Only string can be used here.
Use Tag property of the checkbox to preserve the data you want to refer it. Its good place to store any object and not just string.
Use Parent property of the checkbox to access checkbox's parent properties.
As a best practice, assign a logical name to the dynamic controls. This is the best way to identify the control.
sensorpanel.Name = "panel" + j.ToString();
this.Controls.Add(sensorpanel);
:
:
cb.Text = "Occupancy";
cb.Tag = "panel Index = " + j.ToString();
cb.Name = "panel" + j.ToString() + "_" + "cb_" + cb.Text;
sensorpanel.Controls.Add(cb);
void cb_CheckedChanged(object sender, EventArgs e)
{
CheckBox checkbox = (CheckBox)sender;
string mssg;
mssg = "Name = " + checkbox.Name;
mssg = "tag = " + checkbox.Tag;
mssg = "Parent text = " + checkbox.Parent.Text;
mssg = "Parent name = " + checkbox.Parent.Name;
MessageBox.Show(mssg);
}
I have the following code that I am trying to figure out but I am completely stumped. I am adding the progressbar into the listview, but I really don't know how to access each progressbar to update the progress values.
public ProgressBar LvAddProgB(ListView LV, int LVII, int LVColI, string lvName)
{
Rectangle SizeR = default(Rectangle);
ProgressBar ProgBar = new ProgressBar();
SizeR = LV.Items[LVII].Bounds;
SizeR.Width = LV.Columns[LVColI].Width;
if (LVColI > 0)
{
SizeR.X = SizeR.X + LV.Columns[LVColI - 1].Width;
}
ProgBar.Parent = LV;
ProgBar.Name = lvName;
ProgBar.SetBounds(SizeR.X, SizeR.Y, SizeR.Width, SizeR.Height);
ProgBar.Visible = true;
ProgBar.Maximum = 1000;
ProgBar.Step = 1;
return ProgBar;
}
private void button1_Click(object sender, EventArgs e)
{
for (int x = 0; x < 3; ++x)
{
ListViewItem item = new ListViewItem();
item.Text = "d.Name";
item.SubItems.Add(" ");
listView1.Items.Add(item);
LvAddProgB(listView1, x, 1, "Lview" + x.ToString());
}
}
If you use a key of some sort, you can fish it back out of the Controls collection to update. Since each is displayed as if it was part of the ListView, it seems like there is some sort of linkage between the two. A key will also provide a way to link the item and related ProgressBar.
Assuming your ListView is Details view, just add a subitem at the end, without a related ColumnHeader. The data will not show, but will still be related to the Item. Use the same text as the ProgressBar name and it is easy to find.
My ListView has 3 columns: {Item, Name, Completion}, but the code will add a 4th subitem to store the key:
private void AddLVItem(string key, string name, int value)
{
ListViewItem lvi = new ListViewItem();
ProgressBar pb = new ProgressBar();
lvi.SubItems[0].Text = name;
lvi.SubItems.Add(value.ToString());
lvi.SubItems.Add("");
lvi.SubItems.Add(key); // LV has 3 cols; this wont show
lv.Items.Add(lvi);
Rectangle r = lvi.SubItems[2].Bounds;
pb.SetBounds(r.X, r.Y, r.Width, r.Height);
pb.Minimum = 1;
pb.Maximum = 10;
pb.Value = value;
pb.Name = key; // use the key as the name
lv.Controls.Add(pb);
}
Then, a method to update the Value and Progress bar for a given key:
private void UpdateItemValue(string key, int value)
{
ListViewItem lvi;
ProgressBar pb;
// find the LVI based on the "key" in
lvi = lv.Items.Cast<ListViewItem>().FirstOrDefault(q => q.SubItems[3].Text == key);
if (lvi != null)
lvi.SubItems[1].Text = value.ToString();
pb = lv.Controls.OfType<ProgressBar>().FirstOrDefault(q => q.Name == key);
if (pb != null)
pb.Value = value;
}
usage:
// add some data
AddLVItem("A", "Ziggy", 1);
AddLVItem("B", "Zacky", 1);
AddLVItem("C", "Zoey", 1);
AddLVItem("D", "Zeke", 1);
// update the displayed value and progressbar using the key:
UpdateItemValue("A", 6);
UpdateItemValue("B", 5);
UpdateItemValue("C", 8);
UpdateItemValue("D", 2);
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.listView1 = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader2 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.columnHeader3 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.SuspendLayout();
//
// button1
//
this.button1.Location = new System.Drawing.Point(12, 12);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// listView1
//
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2,
this.columnHeader3});
this.listView1.GridLines = true;
this.listView1.Location = new System.Drawing.Point(12, 64);
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(504, 164);
this.listView1.TabIndex = 1;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Details;
//
// columnHeader1
//
this.columnHeader1.Width = 99;
//
// columnHeader2
//
this.columnHeader2.Width = 117;
//
// columnHeader3
//
this.columnHeader3.Width = 117;
//
// Form1
//
this.ClientSize = new System.Drawing.Size(528, 261);
this.Controls.Add(this.listView1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.VScrollBar vScrollBar1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader columnHeader3;
public ProgressBar LvAddProgB(ListView LV, int X, int Y, string lvName)
{
ProgressBar ProgBar = new ProgressBar();
ProgBar.Parent = LV;
ProgBar.Name = lvName;
ProgBar.Location = new Point(X, Y);
ProgBar.Visible = true;
ProgBar.Maximum = 1000;
ProgBar.Step = 1;
return ProgBar;
}
private void button1_Click(object sender, EventArgs e)
{
for (int x = 0; x < 3; ++x)
{
ListViewItem item = new ListViewItem();
item.Text = "d.Name";
item.SubItems.Add(" ");
listView1.Items.Add(item);
listView1.Controls.Add(LvAddProgB(listView1, item.Position.X + item.Bounds.Width, item.Position.Y, "Lview" + x.ToString()));
}
}
I want to be able to assign each checkbox to it's own richtextbox
I'm making the richtextboxes, then I'm making the checkboxes but how can I "link" them together?
for example :
// richtextbox 1 - > checkbox 1 = false
// richtextbox 2 - > checkbox 2 = true
// richtextbox 3 - > checkbox 3 = true
// richtextbox 4 - > checkbox 4 = false
this is my code:
int n = TodoItems.Count;
RichTextBox[] RichtextBoxes = new RichTextBox[n];
CheckBox[] Checkboxes = new CheckBox[n];
for (int i = 0; i < n; i++)
{
//creating the richtextbox
RichtextBoxes[i] = new RichTextBox();
RichtextBoxes[i].Name = "TB" + i.ToString();
RichtextBoxes[i].Text = TodoItems[i].ToString();
RichtextBoxes[i].Location = new System.Drawing.Point(130, (10 + (60 * i)));
RichtextBoxes[i].Size = new System.Drawing.Size(300, 50);
RichtextBoxes[i].Visible = true;
RichtextBoxes[i].ReadOnly = true;
RichtextBoxes[i].SelectionAlignment = HorizontalAlignment.Center;
RichtextBoxes[i].BackColor = Color.White;
TodoList.Controls.Add(RichtextBoxes[i]);
//creating the checkboxes
Checkboxes[i] = new CheckBox();
Checkboxes[i].Name = "CB" + i.ToString();
Checkboxes[i].Text = "";
Checkboxes[i].Location = new System.Drawing.Point(440, (30 + (60 * i)));
Checkboxes[i].Size = new System.Drawing.Size(18, 17);
Checkboxes[i].Visible = true;
Checkboxes[i].CheckedChanged += new EventHandler(this.CheckedChange);
TodoList.Controls.Add(Checkboxes[i]);
}
I have modified your code please see below, you can access your desired rich text box on checkbox click.
RichTextBox[] RichtextBoxes { get; set; }
CheckBox[] Checkboxes { get; set; }
private void Form1_Load(object sender, EventArgs e)
{
int n = TodoItems.Count;
RichtextBoxes = new RichTextBox[n];
Checkboxes = new CheckBox[n];
for (int i = 0; i < n; i++)
{
//creating the richtextbox
RichtextBoxes[i] = new RichTextBox();
RichtextBoxes[i].Name = "TB-" + i.ToString();
RichtextBoxes[i].Text = TodoItems[i].ToString();
RichtextBoxes[i].Location = new System.Drawing.Point(130, (10 + (60 * i)));
RichtextBoxes[i].Size = new System.Drawing.Size(300, 50);
RichtextBoxes[i].Visible = false;
RichtextBoxes[i].ReadOnly = true;
RichtextBoxes[i].SelectionAlignment = HorizontalAlignment.Center;
RichtextBoxes[i].BackColor = Color.White;
TodoList.Controls.Add(RichtextBoxes[i]);
//creating the checkboxes
Checkboxes[i] = new CheckBox();
Checkboxes[i].Name = "CB-" + i.ToString();
Checkboxes[i].Text = "";
Checkboxes[i].Location = new System.Drawing.Point(440, (30 + (60 * i)));
Checkboxes[i].Size = new System.Drawing.Size(18, 17);
Checkboxes[i].Visible = true;
Checkboxes[i].CheckedChanged += checkBox1_CheckedChanged;
TodoList.Controls.Add(Checkboxes[i]);
}
}
void checkBox1_CheckedChanged(object sender, EventArgs e)
{
CheckBox cb = sender as CheckBox;
string cbName = cb.Name;
int sbNumber = int.Parse(cbName.Split('-')[1]);
RichtextBoxes[sbNumber].Visible = true; // you can get desired richtextbox here and can any thing with it :)
}
I have found the answere, and I'll post it to make your life easyer
when I made the richtextboxes and the checkboxes I set there names to a number
Checkboxes[i].Name = i.ToString();
then I used the event that was provided for me by Mirza Danish Baig
Create and event void checkBox_CheckedChanged(object sender, EventArgs e) { } and then assign this event name Checkboxes[i].CheckedChanged += checkBox_CheckedChanged; –
and after that I started to try things eventualy I came to this :
private void checkBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox ThisCheckbox = (CheckBox)sender;
if (ThisCheckbox.Checked == true)
{
//finding the richtextbox by id...
RichTextBox ThisRichtextbox = this.Controls.Find("TB" + ThisCheckbox.Name, true).FirstOrDefault() as RichTextBox;
try//try and catch for testing, this can be removed later.
{
MessageBox.Show(ThisRichtextbox.Text);
}
catch (Exception Exc)
{
MessageBox.Show(Exc.Message);
}
}
}
I have nested controls inside RadPageView control on a Winform application. RadPageView has a child RadPageViewPage. These two controls are on the form however a tab control and inside that tab control some other controls are added dynamically. How can I find and change the value of the Textbox inside the dynamically generated tab control on a click of the button.
public Form1()
{
InitializeComponent();
TabControl tb = new TabControl();
tb.Width = 500;
TabPage tp = new TabPage("Tab 1");
Label lb = new Label();
lb.Text = "Test";
lb.Location = new Point(10, 10);
TextBox txt = new TextBox();
txt.Text = "Textbox";
txt.Location = new Point(200, 10);
tp.Controls.Add(lb);
tp.Controls.Add(txt);
tb.Controls.Add(tp);
radPageViewPage1.Controls.Add(tb);
}
private void button1_Click(object sender, EventArgs e)
{
}
I have found this example over the internet and its working perfectly.
public Form1()
{
InitializeComponent();
TabControl tb = new TabControl();
tb.Width = 500;
TabPage tp = new TabPage("Tab 1");
Label lb = new Label();
lb.Text = "Test";
lb.Name = "lblTest";
lb.Location = new Point(10, 10);
TextBox txt = new TextBox();
txt.Text = "Textbox";
txt.Name = "txtName";
txt.Location = new Point(200, 10);
tp.Controls.Add(lb);
tp.Controls.Add(txt);
tb.Controls.Add(tp);
radPageViewPage1.Controls.Add(tb);
}
private void button1_Click(object sender, EventArgs e)
{
var crl = FindControl("txtName");
MessageBox.Show(crl.Text);
}
Control FindControl(string target)
{
return FindControl(this, target);
}
static Control FindControl(Control root, string target)
{
if (root.Name.Equals(target))
return root;
for (var i = 0; i < root.Controls.Count; ++i)
{
if (root.Controls[i].Name.Equals(target))
return root.Controls[i];
}
for (var i = 0; i < root.Controls.Count; ++i)
{
Control result;
for (var k = 0; k < root.Controls[i].Controls.Count; ++k)
{
result = FindControl(root.Controls[i].Controls[k], target);
if (result != null)
return result;
}
}
return null;
}
How do I make a kind of grid with colours that can be selected and be saved to a field on selection? Like in the chat options in Twitch.
Windows Form provides the ColorDialog
ColorDialog colorDialog = new ColorDialog();
colorDialog.ShowDialog();
The selected Color could be called with:
colorDialog.Color
All you need is TableLayoutPanel and panel for each cell of it:
public partial class MainForm : Form
{
private Color selected_color;
private List<Color> colors;
public MainForm()
{
InitializeComponent();
colors = new List<Color>();
colors.Add(Color.Red);
colors.Add(Color.Green);
colors.Add(Color.Blue);
colors.Add(Color.Yellow);
colors.Add(Color.Teal);
colors.Add(Color.RosyBrown);
colors.Add(Color.Lime);
colors.Add(Color.Gray);
tableLayoutPanel.CellBorderStyle = TableLayoutPanelCellBorderStyle.OutsetDouble;
for (byte i = 0; i < tableLayoutPanel.Controls.Count; i++)
{
Panel p = tableLayoutPanel.Controls[i] as Panel;
p.BackColor = colors[i];
p.Click += panel_click;
}
}
private void panel_click(object sender, EventArgs e)
{
Panel p = sender as Panel;
selected_color = p.BackColor;
lbl_color.Text = selected_color.ToString();
lbl_color.ForeColor = selected_color;
}
private void btn_showMoreColours_Click(object sender, EventArgs e)
{
Panel[] panels = new Panel[4];
for (byte i = 0; i < panels.Length; i++)
{
panels[i] = new Panel();
panels[i].Dock = DockStyle.Fill;
panels[i].Location = new System.Drawing.Point(3, 3);
panels[i].Name = "panel" + (i + 4);
panels[i].Size = new System.Drawing.Size(123, 100);
panels[i].BackColor = colors[i + 4];
panels[i].Click += panel_click;
tableLayoutPanel.Controls.Add(panels[i]);
}
Size = new Size(Size.Width, Size.Height * 2);
}
}
After clicking a cell you will get Color in field selected_color.
EDIT:
A have added show more colours button as well. It will expand like shown below:
Source code here