Create an event handler for control created programmatically - c#

I am working on a WPF application and what I want is if a specific Radio Button from group A is selected the program creates a second set of Radio Buttons call them group B and at the same time a disabled textbox. Now I want to create an event so if the user Selects option 3 from Group B the text box becomes enabled and when it is unselected it disables again. Now I have the working programmatically but when I try to create the event handlers I am referencing a non-existent control and it won't build. I am trying to use this.textBox.IsEnabled = true/false; to enable/disable the textbox. So just to make sure the actual question is clear. How can I enable/disable a textbox which doesn't exist at build/runtime?
My Events:
private void AllowRegion(object sender, RoutedEventArgs e)
{
this.SpecRegionText.IsEnabled = true;
}
private void DisallowRegion(object sender, RoutedEventArgs e)
{
this.SpecRegionText.IsEnabled = false;
}
Creating the controls:
private void AddSpecificControls()
{
Grid grid = (Grid)this.SpecsGrid;
RadioButton recruitmentEnabled = (RadioButton)this.RecruitmentEnabled;
if ((bool)recruitmentEnabled.IsChecked)
{
RadioButton newNations = new RadioButton();
newNations.Margin = new Thickness(10, 10, 0, 0);
newNations.HorizontalAlignment = HorizontalAlignment.Left;
newNations.Name = "NewNations";
newNations.GroupName = "RecruitType";
newNations.Content = "New Nations";
newNations.Width = 124;
grid.Children.Add(newNations);
RadioButton reFound = new RadioButton();
reFound.Margin = new Thickness(10, 30, 0, 0);
reFound.HorizontalAlignment = HorizontalAlignment.Left;
reFound.Name = "Refound";
reFound.GroupName = "RecruitType";
reFound.Content = "Refounded Nations";
reFound.Width = 124;
grid.Children.Add(reFound);
RadioButton specRegionRadio = new RadioButton();
specRegionRadio.Margin = new Thickness(10, 50, 0, 0);
specRegionRadio.HorizontalAlignment = HorizontalAlignment.Left;
specRegionRadio.VerticalAlignment = VerticalAlignment.Top;
specRegionRadio.Name = "SpecRegionRadio";
specRegionRadio.GroupName = "RecruitType";
specRegionRadio.Content = "Specific Region";
specRegionRadio.Width = 124;
specRegionRadio.Height = 23;
specRegionRadio.Checked += new RoutedEventHandler(AllowRegion);
specRegionRadio.Unchecked += new RoutedEventHandler(DisallowRegion);
grid.Children.Add(specRegionRadio);
TextBox specRegionText = new TextBox();
specRegionText.Margin = new Thickness(139, 50, 0, 0);
specRegionText.HorizontalAlignment = HorizontalAlignment.Left;
specRegionText.VerticalAlignment = VerticalAlignment.Top;
specRegionText.Name = "SpecRegionText";
specRegionText.Text = "Region";
specRegionText.Width = 120;
specRegionText.Height = 23;
specRegionText.IsEnabled = false;
grid.Children.Add(specRegionText);
}
}

You can hook delegate inline using lambda but for that you have to declare textBox before radioButton.
TextBox specRegionText = new TextBox();
RadioButton specRegionRadio = new RadioButton();
specRegionRadio.Checked += (s,e) => specRegionText.IsEnabled = true;
specRegionRadio.Unchecked += (s,e) => specRegionText.IsEnabled = false;

Related

Check all items in a specified checked list box c#

I have created a small kitchen display program that display food orders. So I created dynamically a panel that contains a table layout panel that contains a checked list box and a check all button . My problem is... I have a check all button in each table layout panel created dynamically and every time I click it, it checks all items in the last created CheckedListBox not the clicked one.
This is my code:
p = new Panel();
p.Size = new System.Drawing.Size(360, 500);
p.BorderStyle = BorderStyle.FixedSingle;
p.Name = "panel";
tpanel = new TableLayoutPanel();
tpanel.Name = "tablepanel";
clb = new CheckedListBox();
tpanel.Controls.Add(b1 = new Button() { Text = "CheckAll" }, 1, 4);
b1.Name = "b1";
b1.Click += new EventHandler(CheckAll_Click);
b1.AutoSize = true;
private void CheckAll_Click(object sender, EventArgs e)
{
var buttonClicked = (Button)sender;
var c = GetAll(this, typeof(CheckedListBox));
for (int i = 0; i < c.Count(); i++)
{
\\any help
}
}
public IEnumerable<Control> GetAll(Control control, Type type)
{
var controls = control.Controls.Cast<Control>();
return controls.SelectMany(ctrl => GetAll(ctrl, type)).Concat(controls).Where(c =>
c.GetType() == type);
}
First I will describe the struct
Order = TableLayoutPanel
TableLayoutPanel has 1 CheckAll Button and CheckListBox
And you want when you click to CheckAll Button it will checks exactly all items in current TableLayoutPanel.
So try this code
class XForm : Form {
// create Dictionary to store Button and CheckListBox
IDictionary<Button, CheckListBox> map = new Dictionary<Button, CheckListBox> ();
// when you create new order (new TableLayoutPanel)
// just add map Button and CheckListBox to map
private void CreateOrder () {
var panel = new Panel ();
panel.Size = new System.Drawing.Size (360, 500);
panel.BorderStyle = BorderStyle.FixedSingle;
panel.Name = "panel";
var table = new TableLayoutPanel ();
var checklistBox = new CheckedListBox ();
var button = new Button () { Text = "CheckAll" };
table.Controls.Add (button, 1, 4);
button.Name = "b1";
button.Click += new EventHandler (CheckAll_Click);
button.AutoSize = true;
map[button] = checklistBox;
}
// and on event handle
private void CheckAll_Click (object sender, EventArgs e) {
var buttonClicked = (Button) sender;
var c = map[buttonClicked];
if (c == null) return;
for (int i = 0; i < c.Items.Count; i++)
{
c.SetItemChecked(i, true);
}
}
}
And dont for get remove it from map when remove the order.
Hope it helps

C# WPF Textbox click Event

I create a stackpanel, and put some controls and 1 of these is a textbox, programaticly.
How can i create an event that, when i click on textbox i delete the stackpanel and everything inside?
Here is my code...
System.Windows.Controls.StackPanel Defesa = new StackPanel();
Defesa.Height = 120;
Defesa.Width = 140;
Panel_DE.Children.Add(Defesa);
Defesa.Background = new
SolidColorBrush((Color)ColorConverter.
ConvertFromString("#FF000000"));
Defesa.Margin = new Thickness(20, 0, 0, 0);
Ellipse Foto = new Ellipse();
Foto.Height = 80;
Foto.Width = 80;
Foto.StrokeThickness = 2;
SolidColorBrush borda = new SolidColorBrush();
borda.Color = Colors.White; ;
Foto.Stroke = borda;
Defesa.Children.Add(Foto);
ImageBrush camera = new ImageBrush();
camera.ImageSource = new BitmapImage(new
Uri(#"C:\Users\Vitor\documents\visual studio 2013\Projects\Manager
Treinador\Manager Treinador\Icons\photo-camera w.png"));
Foto.Fill = camera;
System.Windows.Controls.TextBlock Nome_def = new TextBlock();
Nome_def.Text = def_name;
Nome_def.Foreground = new
SolidColorBrush((Color)ColorConverter.ConvertFromString
("#FFF9F4F4"));
Nome_def.HorizontalAlignment = HorizontalAlignment.Center;
Defesa.Children.Add(Nome_def);
System.Windows.Controls.StackPanel Panel = new StackPanel();
Panel.Orientation = Orientation.Horizontal;
Defesa.Children.Add(Panel);
System.Windows.Controls.TextBlock But_Delet = new TextBlock();
But_Delet.Text = "X";
But_Delet.FontWeight = FontWeights.Bold;
But_Delet.Foreground = new
SolidColorBrush((Color)ColorConverter.ConvertFromString
("#FFF90707"));
Panel.Children.Add(But_Delet);
But_Delet.HorizontalAlignment = HorizontalAlignment.Left;
But_Delet.Cursor = Cursors.Hand;
But_Delete is the text box that i want to remove all...
Thanks
Since a TextBlock does not have a click event, you will need to simulate this by using OnPreviewMouseDown event. To do this:
add this to the end of your code:
But_Delet.PreviewMouseDown += ButDeletOnPreviewMouseDown;
Then add this event handler:
private void ButDeletOnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Panel_DE.Children.Remove(Defesa);
}
However, if there is a chance you will need to restore these controls, it would better to hide them using this event handler instead:
private void ButDeletOnPreviewMouseDown(object sender, MouseButtonEventArgs e)
{
Defesa.Visibility = Visibility.Hidden;
}

Windows Forms C# Dynamic controls problem

I'm trying to make a form where the user can add group boxes with other controls inside.
groupboxes and other controls are all created dynamically.
Program image. *the button "Adicionar Pergunta" adds a new group box
Inside the groupbox is a combobox where the user can choose the preset of controls inside the groupbox.
each preset have different controls or controls in different locations of the group box.
my problem is that when the user change the preset of one groupbox all the other combobox stop working.
Here is the my script:
Variables:
int groupboxcount = 2;
RadioButton rb1 = new RadioButton();
RadioButton rb2 = new RadioButton();
TextBox tx1 = new TextBox();
TextBox tx2 = new TextBox();
GroupBox gb;
ComboBox cb;
RadioButton rb_1;
RadioButton rb_2;
RadioButton rb_V;
RadioButton rb_F;
TextBox tx_1;
TextBox tx_2;
Button Click:
{
gb = new GroupBox();
NumericUpDown Nud1 = new NumericUpDown();
cb = new ComboBox();
cb.SelectedIndexChanged += new EventHandler(cb2_selectec_index_changed);
RichTextBox RichTextBox2 = new RichTextBox();
Label labelA1 = new Label();
Label labelA2 = new Label();
Label labelA3 = new Label();
gb.Name = "groupBox" + groupboxcount;
gb.Text = "Pergunta ";
gb.Height = 182;
gb.Width = 520;
gb.Location = new Point(groupBox1.Location.X, gb.Location.Y + gb.Height + 125);
Nud1.Height = 20;
Nud1.Width = 41;
Nud1.Location = new Point(6, 37);
Nud1.Value = groupboxcount;
cb.Items.Add("Enunciado");
cb.Items.Add("Pergunta normal");
cb.Items.Add("Escolha multipla");
cb.Items.Add("Verdadeiro/Falso");
cb.Height = 21;
cb.Width = 121;
cb.Location = new Point(53, 36);
RichTextBox2.Height = 80;
RichTextBox2.Width = 249;
RichTextBox2.Location = new Point(211, 37);
labelA1.Text = "Nº";
labelA2.Text = "Tipo de pergunta";
labelA3.Text = "Pergunta";
labelA1.Location = new Point(6, 19);
labelA2.Location = new Point(59, 19);
labelA3.Location = new Point(208, 19);
labelA1.Width = 20;
this.Controls.Add(gb);
gb.Controls.Add(Nud1);
gb.Controls.Add(cb);
gb.Controls.Add(RichTextBox2);
gb.Controls.Add(labelA1);
gb.Controls.Add(labelA2);
gb.Controls.Add(labelA3);
button1.Location = new Point(button1.Location.X, gb.Location.Y + button1.Height + 200);
groupboxcount++;
}
Combobox cb2 selected index changed:
{
if (cb.SelectedIndex == 0)
{
//Apenas mostra enunciado
}
if (cb.SelectedIndex == 1)
{
//recebe resposta
}
if (cb.SelectedIndex == 2)
{
rb_1 = new RadioButton();
rb_2 = new RadioButton();
tx_1 = new TextBox();
tx_2 = new TextBox();
rb_1.Text = "opção 1";
rb_1.Location = new Point(120, 75);
rb_2.Text = "opção 2";
rb_2.Location = new Point(120, 100);
tx_2.Location = new Point(5, 100);
tx_1.Location = new Point(5, 75);
this.gb.Controls.Add(rb_1);
this.gb.Controls.Add(rb_2);
this.gb.Controls.Add(tx_1);
this.gb.Controls.Add(tx_2);
}
else
{
this.gb.Controls.Remove(rb_1);
this.gb.Controls.Remove(rb_2);
this.gb.Controls.Remove(tx_1);
this.gb.Controls.Remove(tx_2);
}
if (cb.SelectedIndex == 3)
{
rb_V = new RadioButton();
rb_F = new RadioButton();
rb_V.Text = "Verdadeiro";
rb_V.Location = new Point(120, 75);
rb_F.Text = "Falso";
rb_F.Location = new Point(120, 100);
this.gb.Controls.Add(rb_V);
this.gb.Controls.Add(rb_F);
}
else
{
this.gb.Controls.Remove(rb_V);
this.gb.Controls.Remove(rb_F);
}
}
I would appreciate if you could help me.

C# WinForms TableLayoutPanel is flickering while adding my row and How to stop it

This code works fine like adding a row and deleting a row dynamically .But when i delete some of rows from table and then click the add button to add some rows into the panel then the flickering starts and increases while adding more rows.
Public Global Variables
public TableLayoutPanel table;
public int tablecol, tablerow;
Function for creating a table in Main Window.
This function creates a table with some header labels and Button named "ADD" .
public void createtable()
{
Label title = new Label(); title.Text = "Table Name";
this.myw.right_panel.Controls.Add(title);
TextBox tname = new TextBox(); tname.Width = 300;
this.myw.right_panel.Controls.Add(tname);
Button addrowbtn = new Button(); addrowbtn.Text = "ADD ROW";
addrowbtn.Click += addrowbtn_Click;
this.myw.right_panel.Controls.Add(addrowbtn);
table = new TableLayoutPanel();
table.Width = this.myw.right_panel.Width;
table.Height = 400;
table.AutoScroll = true;
table.ColumnCount = 9;
int col = 0;
Label[] titlelbl = new Label[9];
foreach(Label l in titlelbl)
{
titlelbl[col++] = new Label();
}
titlelbl[0].Text = "NAME";
titlelbl[0].Width = 200;
titlelbl[1].Text = "TYPE";
titlelbl[2].Text = "NOT NULL";
titlelbl[3].Text = "PK";
titlelbl[4].Text = "AI";
titlelbl[5].Text = "U";
titlelbl[6].Text = "DEFAULT";
titlelbl[7].Text = "CHECK";
titlelbl[8].Text = "DELETE";
col = 0;
FlowLayoutPanel headerpanel = new FlowLayoutPanel();
headerpanel.Width = this.myw.right_panel.Width;
headerpanel.AutoSize = true;
foreach(Label l in titlelbl)
{
l.BackColor = Color.LightGray;
l.TextAlign = ContentAlignment.MiddleCenter;
headerpanel.Controls.Add(l);
}
this.myw.right_panel.Controls.Add(headerpanel);
this.myw.right_panel.Controls.Add(table);
}
This Function is used to create a dynamic row in the table .Each row contains a button named "DEL"
void addrowbtn_Click(object sender, EventArgs e)
{
TextBox name = new TextBox(); name.Width = 200;
ComboBox type = new ComboBox();
type.Items.AddRange(new string[] {"INTEGER","TEXT","BLOB","NUMERIC","REAL"});
CheckBox notnull = new CheckBox();
CheckBox pk = new CheckBox();
CheckBox ai = new CheckBox();
CheckBox u = new CheckBox();
TextBox def = new TextBox(); def.Width = 100;
TextBox check = new TextBox(); check.Width = 100;
Button delbtn = new Button(); delbtn.Text = "DEL";delbtn.AutoSize = true;
delbtn.Click += Delbtn_Click;
table.Controls.Add(name, 0, tablerow);
table.Controls.Add(type, 1, tablerow);
table.Controls.Add(notnull, 2, tablerow);
table.Controls.Add(pk, 3, tablerow);
table.Controls.Add(ai,4, tablerow);
table.Controls.Add(u, 5, tablerow);
table.Controls.Add(def, 6, tablerow);
table.Controls.Add(check,7, tablerow);
table.Controls.Add(delbtn, 8, tablerow);
tablerow++;
}
Function for Deleting a Row,
This function will be called whenever a delete button on the table row clicks
private void Delbtn_Click(object sender, EventArgs e)
{
TableLayoutPanelCellPosition tlpcp = new TableLayoutPanelCellPosition();
tlpcp = table.GetPositionFromControl((Control)sender);
for (int i = 0; i < table.ColumnCount; i++)
{
var control = table.GetControlFromPosition(i, tlpcp.Row);
table.Controls.Remove(control);
}
}
Any code improvement suggestions are welcome.

How to set different events for dynamically created element

Im trying to create event with different index for dynamically created GroupBox. With my actual code event for every groupbox is that same. How can i make event with different index for every groupbox? My Code:
public void LoadGry()
{
// GroupBox groupbox = new GroupBox();
Label nazwagry = new Label();
for(int i = 0; i < myCollection.Count; i++)
{
GroupBox groupbox = new GroupBox();
groupbox.Text = myCollection[i];
groupbox.Size = new Size(290, 131);
groupbox.Location = new Point(6, 150 * (myCollection.Count - i - 1));
groupbox.ForeColor = Color.White;
Label label1 = new Label();
label1.Text = groupbox.Text;
label1.AutoSize = true;
label1.Location = new Point(groupbox.Location.X + 80, groupbox.Location.Y + 20);
groupbox.Controls.Add(label1);
Gry.Controls.Add(label1);
PictureBox picturebox = new PictureBox();
picturebox.Location = new Point(groupbox.Location.X + 5, groupbox.Location.Y + 20);
picturebox.Size = new Size(75, 75);
picturebox.SizeMode = PictureBoxSizeMode.StretchImage;
picturebox.LoadAsync(myCollection3[i]);
groupbox.Click += new EventHandler(delegate {groupboxclick(groupbox, picturebox, i);});
Label label2 = new Label();
label2.Text = "Status: " + "Aktualny";
label2.ForeColor = Color.Green;
label2.AutoSize = true;
label2.Location = new Point(label1.Location.X, label1.Location.Y + 20);
Gry.Controls.Add(label2);
Label zapiszopis = new Label();
zapiszopis.Text = myCollection4[i];
zapiszopis.Visible = false;
Gry.Controls.Add((Control)groupbox);
//MessageBox.Show("pokaz mi wysokosc");
}
}
private void groupboxclick(GroupBox groupbox, PictureBox picturebox, int itest)
{
groupbox.ForeColor = Color.Aqua;
this.pictureBox1.BackgroundImage = picturebox.BackgroundImage;
opishacka.Text = myCollection4[itest];
}
The problem is that the event setup is using the variable K value. For use the number instead you probably needs to create an expression manually to use the current value in each case.
BUT
You can easily do what you want using the following properties to attach values to controls.
1-) Tag in WinForms & WPF:
// Setup
pictureBox.Tag = i;
// Event
int i = (int) pictureBox.Tag;
2-) ViewState in WebForms
// Setup
ViewState[pictureBox.UniqueID] = i;
// Event
int i = (int) ViewState[pictureBox.UniqueID];
You can use many other techniques. I only post one for each popular framework. I guest that you are in a WinFors project.
Hope this help!

Categories