I need to know if it is possible to call a control and also attach it's events from a class. I have been researching the internet for a some valuable information but to no avail. Below is a simple illustration of what I intend achieving.
PAGE
protected void Page_Load(object sender, EventArgs e)
{
DynamicControls(IsPostBack);
}
public void DynamicControls(bool posting_back)
{
ControlHandler ch = new ControlHandler();
CreateTextbox(item.id, item.value, item.textMode, item.mandatoryInput, item.maxLength,int.Parse(item.rowNumber), int.Parse(item.colNumber), item.visible, item.autoPostBack,item.enable, table);
}
CLASS
public void CreateTextbox(String id, String value, String textMode, bool mandatoryInput
, String maxLength, int rowNumber, int colNumber, bool visible, bool autopostBack, bool enable, Table table)
{
TextBox tb = new TextBox();
tb.ID = id;
tb.Text = value == null ? "" : value;
tb.TextMode = textMode == null ? TextBoxMode.SingleLine : textMode.ToLower() == "multiline" ? TextBoxMode.MultiLine : TextBoxMode.SingleLine;
tb.MaxLength = maxLength == null ? 32500 : int.Parse(maxLength);
tb.Visible = visible;
tb.Style.Add("width", "80%");
tb.Enabled = enable;
tb.AutoPostBack = autopostBack;
tb.Font.Bold = true;
tb.ForeColor = System.Drawing.Color.Chocolate;
tb.TextChanged += new EventHandler(tb_TextChanged);
}
protected void tb_TextChanged(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
tb.Text = //some values or display in another control in the form
}
Thanks
It is possible to listen to events yes. Though dynamic controls should always be created during page preinit or page init, not load.
Related
I created a usercontrol textbox named ucTextBox contains a label, a textbox and two buttons. I put it many in my form.
Now I want to attach a MouseHover event on each ucTextBox,TextBox and MaskedTextBox in my form.
I do this :
public void AttachHoverEvent(Control CTrl)
{
foreach (Control c in CTrl.Controls)
{
if (c is TextBox || c is MaskedTextBox)
{
c.MouseHover += new EventHandler(afficheDictionnaireChamp);
c.MouseLeave += new EventHandler(desafficheDictionnaireChamp);
continue;
}
if (c is ucTextBox)
{
c.MouseHover += new EventHandler(afficheDictionnaireChamp);
c.MouseLeave += new EventHandler(desafficheDictionnaireChamp);
continue;
}
if (c.HasChildren)
{
AttachHoverEvent(c);
}
}
}
Note : I put ucTextBox in other condition to put a breakpoint and the condition is true.
My code works correctly for TextBox and MaskedTextBox but don't work on my
ucTextBox (Nothing happen).
I try to add this in my ucTextBox class :
private void txbValeur_MouseHover(object sender, EventArgs e)
{
if (this.MouseHover != null)
this.MouseHover(this, e);
}
This my target events function :
public void afficheDictionnaireChamp(object sender, EventArgs e)
{
Dictionnaire dico = new Dictionnaire();
Control snd = (Control)sender;
string table = dico.getNomTable(this.Name, snd.Name);
string champ = dico.getNomChamp(this.Name, snd.Name);
if (table != "" && champ != "")
Globals.FormMain.tslTable.Text = table + " - " + champ;
else
Globals.FormMain.tslTable.Text = "";
}
public void desafficheDictionnaireChamp(object sender, EventArgs e)
{
Globals.FormMain.tslTable.Text = "";
}
If someone got an idea where the problem can from ?
Thanks in advance !
Thomas
Try to set your parent controls background to "Transparent"
I programmatically create a Form with two textboxes. My goal is to disable one textbox if I type something in the second one and contrariwise. I managed to disable second textbox on first textbox textchange,but can't figure out how enable it when the first textbox.Text is empty.
Here is the code :
private void metaName_TextChanged(object sender,EventArgs e)
{
var ctrl = (Control)sender;
var frm = ctrl.FindForm();
TextBox metaTxt = null;
foreach (var ctr in frm.Controls)
{
if (ctr is TextBox)
{
metaTxt = (TextBox)ctr;
if (metaTxt.Name == "metaHTTPEquiv")
{
metaTxt.Enabled = false;
}
else
if (?)
{
}
}
}
}
I want to make something like this :
if(textBox3.Text == String.Empty)
{
textBox4.Enabled = true;
}
else
if(textBox3.Text != String.Empty)
{
textBox4.Enabled = false;
}
You can check only the textchanged event for each one like the following:
private void textBox1_TextChanged(object sender, EventArgs e)
{
textBox2.Enabled = !(textBox1.Text.Length >= 1);
}
private void textBox2_TextChanged(object sender, EventArgs e)
{
textBox1.Enabled = !(textBox2.Text.Length >= 1);
}
The self textbox has some values, then the enabled will be false for the other one
First set a flag to enable or disable the second control based on the content of the metaName textbox that raises the event, then search for the second textbox using a bit of Linq.
private void metaName_TextChanged(object sender,EventArgs e)
{
TextBox ctrl = sender as TextBox;
if(ctrl != null)
{
bool enable = !string.IsNullOrEmpty(ctrl.Text);
TextBox secondOne = this.Controls
.OfType<TextBox>()
.FirstOrDefault(x => x.Name == "metaHTTPEquiv");
if(secondOne != null)
secondOne.Enabled = enable;
}
}
The same code, reversing the textboxes roles, could be used as the event handler of the second textbox.
Forget about control events and use data binding.
Take the following helper method
static void Bind(Control target, string targetProperty, object source, string sourceProperty, Func<object, object> expression)
{
var binding = new Binding(targetProperty, source, sourceProperty, true, DataSourceUpdateMode.Never);
binding.Format += (sender, e) => e.Value = expression(e.Value);
target.DataBindings.Add(binding);
}
and just add something like this in your form load event
Bind(textBox2, "Enabled", textBox1, "Text", value => string.IsNullOrEmpty((string)value));
I have a GridView in which i have this column :
bandedGridColumn.ColumnEdit = InitEdit_Material();
Here is the InitEdit_Material method :
public static RepositoryItemLookUpEdit InitEdit_Material()
{
RepositoryItemLookUpEdit riMaterial = new RepositoryItemLookUpEdit();
riMaterial.Columns.Add(new LookUpColumnInfo("ID", "ID"));
riMaterial.Columns.Add(new LookUpColumnInfo("CustomsMaterial.Name", "Name"));
riMaterial.DataSource = Service.GetAll(svc.EntityTypeToGet.Material).Data.All_Material;
riMaterial.DisplayMember = "MaterialFullname";
riMaterial.ValueMember = "ID";
riMaterial.AutoSearchColumnIndex = 1;
riMaterial.BestFitMode = BestFitMode.BestFitResizePopup;
riMaterial.NullText = "";
return riMaterial;
}
This is what it looks like :
I want to perform some actions (set other cell's value based on current cell value) whenever user choose a new value in this cell, but the problem is all the possible event i know only fires once the cell lost focus, i've tried :
private void vwVD_ValidatingEditor(object sender, BaseContainerValidateEditorEventArgs e)
{
if (vwVD.FocusedColumn.Name == "colMaterialID")
MessageBox.Show("only show when focus lost");
return;
}
private void vwVD_CellValueChanged(object sender, CellValueChangedEventArgs e)
{
if (e.Column.Name != "colMaterialID") return;
MessageBox.Show("only show when focus lost");
}
You can try to use GridView.CellValueChanging event:
private void vwVD_CellValueChanging(object sender, CellValueChangedEventArgs e)
{
if (vwVD.FocusedColumn.Name == "colMaterialID")
{
//Perform some actions. Use e.Value.
}
}
I created dynamically some textboxes. They are created after click on one button(number of the textboxes depends on the user).
protected void Button1_Click(object sender, EventArgs e)
{
int i = Convert.ToInt32(TextBox2.Text);
Table tbl = new Table();
tbl.Width = Unit.Percentage(80);
TableRow tr;
TableCell tc;
TextBox txt;
CheckBox cbk;
DropDownList ddl;
Label lbl;
Button btn;
for (int j = 1; j <= i; j++)
{
tr = new TableRow();
tc = new TableCell();
tc.Width = Unit.Percentage(25);
lbl = new Label();
lbl.Text = "Pitanje:";
tc.Controls.Add(lbl);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
txt = new TextBox();
txt.ID = "txt_p_" + j;
tc.Controls.Add(txt);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
lbl = new Label();
lbl.Text = "Odgovori:";
tc.Controls.Add(lbl);
tr.Cells.Add(tc);
tc.Width = Unit.Percentage(25);
txt = new TextBox();
txt.ID = "txt_o_" + j;
tc.Controls.Add(txt);
tr.Cells.Add(tc);
tbl.Rows.Add(tr);
}
Panel1.Controls.Add(tbl);
}
now I need to get the text that is typed into that textboxes. I tried with something that I found on the internet but can't get it to work.
protected void SpremiPitanja(object sender, EventArgs e)
{
int i = Convert.ToInt32(TextBox2.Text);
for (int j = 1; j <= i; j++)
{
***************************************
}
}
any kind of help is welcome. if you need more information I will give them
A variable declared in a function is only visible in a function. You need to store the TextBoxes in a variable, that exists even when the code in the function has "finished". For more information search for scopes.
Here is a small sample that stores TextBoxes in a List that is visible in your class.
Another option would be to use eventhandlers. It depends on your scenario, which solution would be suited better. If you store the TextBoxes in a List, you can easily perform clean up code (for instance remove EventHandlers if required). You can obviously combine Approach 1 and 2. In that case you would store the created TextBox in a List (or any other collection), but you would still use the sender in the eventhandler to get a reference to the sending TextBox.
public partial class Form1 : Form
{
List<TextBox> textBoxes = new List<TextBox>();
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Approach 1: create and add textbox to list
TextBox createdTextbox = new TextBox();
textBoxes.Add(createdTextbox);
}
private void button2_Click(object sender, EventArgs e)
{
//use the textboxes from the list
foreach(TextBox t in textBoxes)
{
//do something with t
}
}
private void button3_Click(object sender, EventArgs e)
{
//Approach 2: use eventhandlers and don't store textbox in a list
TextBox createdTextbox = new TextBox();
createdTextbox.TextChanged += createdTextbox_TextChanged;
listBox1.Items.Add(createdTextbox);
}
void createdTextbox_TextChanged(object sender, EventArgs e)
{
TextBox t = sender as TextBox;
if (t == null)
throw new ArgumentException("sender not of type TextBox", "sender");
//do something with t
}
}
You add textboxes the same way you do, this is my example (sorry it's vb.net):
Dim t As New TextBox With {.ID = "txt_123", .Text = "Vpiši"}
PlaceHolder1.Controls.Add(t)
t = New TextBox With {.ID = "txt_456", .Text = "Briši"}
PlaceHolder1.Controls.Add(t)
And then you iterate through controls in Placeholder (in my example):
Dim tItem As TextBox
Dim tValue As String = String.Empty
For Each c As Control In PlaceHolder1.Controls
If TypeOf c Is TextBox Then
tItem = c
tValue = tItem.Text.ToString
End If
Next
C# example added
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
TextBox t = new TextBox();
t.Text = "Vpiši";
t.ID = "txt_123";
PlaceHolder1.Controls.Add(t);
t = new TextBox();
t.Text = "Briši";
t.ID = "txt_456";
PlaceHolder1.Controls.Add(t);
}
}
protected void Button1_Click(object sender, EventArgs e)
{
TextBox tItem;
String tValue;
foreach (Control c in PlaceHolder1.Controls)
{
if (c.GetType() == typeof(TextBox))
{
tItem = (TextBox)c;
tValue = tItem.Text;
}
}
}
How can I get a value returned from the checkbox_CheckChanged event please? Its a winforms app, and both the form and the checkbox are created programmatically. Thanks for all and any help.
The Controls event handlers are always "void" and you cant change the return type. Instead you can take an external variable and you change that value only in when the CheckedChanged Event occurs.
public bool checkedthecheckbox { get; set; }
CheckBox testchbox = new CheckBox();
private void Form1_Load(object sender, EventArgs e)
{
testchbox.CheckedChanged += new EventHandler(testchbox_CheckedChanged);
}
void testchbox_CheckedChanged(object sender, EventArgs e)
{
if (testchbox.Checked)
checkedthecheckbox = true;
else
checkedthecheckbox = false;
}
You can get the value from 'sender' object.
CheckBox chk = (CheckBox) sender;
bool result = chk.Checked;
You can get the state of the Checkbox by casting the sender object from the event arguments:
public void Method1()
{
CheckBox checkBox = new CheckBox();
checkBox.CheckedChanged += new EventHandler(checkBox_CheckedChanged);
}
void checkBox_CheckedChanged(object sender, EventArgs e)
{
CheckBox c = (CheckBox)sender;
bool resutlt = c.Checked;
}
Hope this helps!
You can use CheckState.Checked or CheckState.Unchecked, which is built in C#. Example:
for (int i = 0; i < lsbx_layers.Items.Count; i++) {
if (lsbx_layers.GetItemCheckState(i) == CheckState.Checked) {
//set boolean variable to true
} else if (lsbx_layers.GetItemCheckState(i) == CheckState.Unchecked) {
//set boolean variable to false
}
}
I've got an alternative to change the regular check box changed event into an event that provides you with the changed Checked value directly.
You could, for example, use it this way:
var myForm = new MyForm();
myForm.CheckBoxChanged += v =>
{
Console.WriteLine("The value of the checkbox changed to {0}", v);
};
Here's the class definition:
public class MyForm
{
public event Action<bool> CheckBoxChanged;
private CheckBox testchbox = new CheckBox();
private void Form1_Load(object sender, EventArgs e)
{
testchbox.CheckedChanged += (s, e) =>
{
var cbc = this.CheckBoxChanged;
if (cbc != null)
{
cbc(testchbox.Checked);
}
};
}
}
I hope this helps.