Scrolling DataGridView with buttons - c#

Hello I have a code where I inside of a datagridview generate buttons with data from sql server database. But now I want to scroll them through buttons. I tried lots of things all gives me error already saw a post about this but nothing worked for me can someone help.
<-----------------------------------My code------------------------------------->
Methods to fill the datagridview:
public void TabelaFuncionario()
{
try
{
BDfuncionarios = new DataTable();
string cmd = "My select string";
var adpt = fConexao.GetDataAdapter(cmd);
BDfuncionarios.Clear();
adpt.Fill(BDfuncionarios);
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
public void BotaoFuncionario()
{
try
{
TabelaFuncionario();
PosXartigo = 1;
PosYartigo = 1;
//Apagar o painel todo
dataGridView1.Controls.Clear();
foreach (DataRow row in BDfuncionarios.Rows)
{
int posicaoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
if (posicaoX > maximoxArtigo)
{
PosYartigo++; PosXartigo = 1;
}
else
{
PosXartigo = PosXartigo != 1 ? PosXartigo++ : 1;
}
int PontoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
int PontoY = ((PosYartigo - 1) * Gap_Yartigo) + yInicial + (Altura_BotaoArtigo * (PosYartigo - 1));
Button bt1 = new Button();
bt1.Location = new Point(PontoX, PontoY);
Mo mo = new Mo();
mo.codmo = (int)row["Something"];
mo.nome_func = (string)row["Something"];
bt1.Name = "Botao" + NBotoes.ToString();
bt1.Height = Altura_BotaoArtigo;
bt1.Width = Largura_BotaoArtigo;
bt1.BackColor = Color.Tan;
bt1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
bt1.ForeColor = Color.Black;
bt1.Text = mo.nome_func;
bt1.Tag = mo;
bt1.FlatStyle = FlatStyle.Popup;
bt1.Click += btArtigo_click;
dataGridView1.Controls.Add(bt1);
NBotoes++;
PosXartigo++;
}
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
Image of my form (don't know if it helps):
http://imgur.com/f5G25nX
<--------------------------EDITED--------------------------------->
i have tried things like this :https://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.rowcount(v=vs.110).aspx
Gives me out of range or something like that
And tried this just now
int row = dataGridView1.RowCount;
MessageBox.Show(row+"");
And it displays me 0; how can i have buttons inside my grid but have 0 rows?

I solved the problem using this panel instead of datagrid for what u wanted it was much better the code will be below:
Methods:
public void TabelaFuncionario()
{
try
{
BDfuncionarios = new DataTable();
string cmd = "your select";
var adpt = fConexao.GetDataAdapter(cmd);
BDfuncionarios.Clear();
adpt.Fill(BDfuncionarios);
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
public void BotaoFuncionario()
{
try
{
TabelaFuncionario();
PosXartigo = 1;
PosYartigo = 1;
//Apagar o painel todo
panel2.Controls.Clear();
foreach (DataRow row in BDfuncionarios.Rows)
{
int posicaoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
if (posicaoX > maximoxArtigo)
{
PosYartigo++; PosXartigo = 1;
}
else
{
PosXartigo = PosXartigo != 1 ? PosXartigo++ : 1;
}
int PontoX = ((PosXartigo - 1) * Gap_Xartigo) + xInicial + (Largura_BotaoArtigo * (PosXartigo - 1));
int PontoY = ((PosYartigo - 1) * Gap_Yartigo) + yInicial + (Altura_BotaoArtigo * (PosYartigo - 1));
Button bt1 = new Button();
bt1.Location = new Point(PontoX, PontoY);
Mo mo = new Mo();
mo.codmo = (int)row["Var1"];
mo.nome_func = (string)row["Var2"];
bt1.Name = "Botao" + NBotoes.ToString();
bt1.Height = Altura_BotaoArtigo;
bt1.Width = Largura_BotaoArtigo;
bt1.BackColor = Color.Tan;
bt1.Font = new System.Drawing.Font("Tahoma", 9F, System.Drawing.FontStyle.Bold);
bt1.ForeColor = Color.Black;
bt1.Text = mo.nome_func;
bt1.Tag = mo;
bt1.FlatStyle = FlatStyle.Popup;
bt1.Click += btFuncionario_click;
panel2.Controls.Add(bt1);
NBotoes++;
PosXartigo++;
}
}
catch (Exception r)
{
MessageBox.Show(r.Message);
}
}
Now the PainelExtension class:
public static class PanelExtension
{
public static void ScrollDown(this Panel p, int pos)
{
//pos passed in should be positive
using (Control c = new Control() { Parent = p, Height = 1, Top = p.ClientSize.Height + pos })
{
p.ScrollControlIntoView(c);
}
}
public static void ScrollUp(this Panel p, int pos)
{
//pos passed in should be negative
using (Control c = new Control() { Parent = p, Height = 1, Top = pos })
{
p.ScrollControlIntoView(c);
}
}
}
The up and down button click:
private void upbt_Click(object sender, EventArgs e)
{
if (i >= 0) i = -1;
panel2.ScrollUp(i=i-30);
}
private void downbt_Click(object sender, EventArgs e)
{
if (i < 0) i = 0;
panel2.ScrollDown(i=i+20);
}
I got it to work like this maybe there were other ways to do it i choose this one.

Related

C# Chart growing outside of panel

My goal is to create a chart that will sit inside of a panel restricting it's size.
I managed to achieve this some time ago but today I noticed that the chart was growing inside of the panel, not allowing the data to be seen.
I have attached a picture bellow which should help understand the issue.
UPDATE
I noticed that if I rmeove 'bottom' from the Anchor property of the panel the chart does not exceed the parent panel but it does not increase with the change of the form which is what I'm looking for.
I also noticed that there was also another chart on the form that was exceeding the parent form, this time the chart would extend to the right not allowing to see the data.
This is the code that generates this second chart and places is inside of the parent panel.
panel_chart.Controls.Clear();
chart1 = new Chart();
chart1.MouseMove += chart1_MouseMove;
chart1.ChartAreas.Add(new ChartArea("chartArea1"));
chart1.Series.Clear();
chart1.Titles.Clear();
var serieOEE = new Series("OEE");
serieOEE.ChartType = SeriesChartType.Line;
serieOEE.XValueType = ChartValueType.String;
var serieProd = new Series("Prod");
serieProd.ChartType = SeriesChartType.Column;
serieProd.XValueType = ChartValueType.String;
var serieDisp = new Series("Disp");
serieDisp.ChartType = SeriesChartType.Column;
serieDisp.XValueType = ChartValueType.String;
var serieQual = new Series("Qual");
serieQual.ChartType = SeriesChartType.Column;
serieQual.XValueType = ChartValueType.String;
DateTime DataReg = DateTime.MinValue;
List<AreaOEE> listaChart = new List<AreaOEE>();
foreach (var item in ListaGrafico) //listaOEE
{
if (item.Designacao == DesignacaoLista)
{
listaChart.Add(item);
}
}
listaChart = listaChart.OrderBy(a => a.IDReg).ToList();
DateTime DataUltimoReg = DateTime.MinValue;
int j = 0;
foreach (var item in listaChart)
{
string HoraGraf = Convert.ToDateTime(item.Hora).ToString("HH:mm");
if (j == 0 || j == listaChart.Count - 1 ||
Math.Abs(Convert.ToDateTime(item.Hora).Subtract(DataUltimoReg).TotalMinutes) >= 30)
{
serieOEE.Points.AddXY(HoraGraf, item.OEE);
serieProd.Points.AddXY(HoraGraf, item.Produtividade);
serieQual.Points.AddXY(HoraGraf, item.Qualidade);
serieDisp.Points.AddXY(HoraGraf, item.Disponibilidade);
DataUltimoReg = Convert.ToDateTime(item.Hora);
if (j == listaChart.Count - 2)
{
break;
}
}
j++;
}
//Adicionar o ultimo
foreach (var item in listaOEE)
{
if (item.Designacao == DesignacaoLista)
{
string sHora = "";
try
{
sHora = item.Hora.Substring(1, 5);
}
catch (Exception ex)
{
string sEx = ex.Message;
}
foreach (var itemOee in serieOEE.Points)
{
if (itemOee.AxisLabel == sHora)
{
itemOee.YValues[0] = item.OEE;
}
}
foreach (var itemP in serieProd.Points)
{
if (itemP.AxisLabel == sHora)
itemP.YValues[0] = item.Produtividade;
}
foreach (var itemD in serieDisp.Points)
{
if (itemD.AxisLabel == sHora)
itemD.YValues[0] = item.Disponibilidade;
}
foreach (var itemQ in serieQual.Points)
{
if (itemQ.AxisLabel == sHora)
itemQ.YValues[0] = item.Qualidade;
}
}
}
chart1.Series.Add(serieProd);
chart1.Series.Add(serieQual);
chart1.Series.Add(serieDisp);
chart1.Series.Add(serieOEE);
serieOEE.BorderWidth = 4;
chart1.ChartAreas[0].AxisX.LabelStyle.Angle = 90;
chart1.ChartAreas[0].AxisX.Interval = 1;
chart1.ChartAreas[0].AxisY.Minimum = 0;
chart1.ChartAreas[0].AxisY.Maximum = 140;
chart1.Legends.Clear();
chart1.Legends.Add(serieOEE.Legend);
chart1.Titles.Add(DesignacaoLista + " " + DataTitulo.ToString("dd-MM HH:mm"));
chart1.Titles[0].Font = new Font("Arial", 13, FontStyle.Bold);
chart1.Visible = true;
chart1.Dock = DockStyle.Fill;
panel_chart.Controls.Add(chart1);
you can change the size of Chart with Chart.Size:
Chart1.Size = new Size(1000, 200); //1000px * 200px

How to display value from not selected combobox c#

I need to display an unselected ComboBox value.
I have 10 ComboBoxes with tag values 1 through 10.
When I select a ComboBox with a tag value of 1, I have to check what is displayed from the ComboBox that has a tag value of 2.
Selecting a ComboBox with a tag value of 5 should give me the value of the ComboBox that has a tag value of 6.
public partial class workPlacePlan : Form
{
public workPlacePlan()
{
InitializeComponent();
}
private void workPlacePlan_Load(object sender, EventArgs e)
{
this.MaximumSize = this.Size;
this.MinimumSize = this.Size;
int cboId;
int i = 1;
string cboName; int c = 1;
var items = new Dictionary<int, string>();
ComboBox[] cbo = {
cbo_1, cbo_2
};
foreach(ComboBox cbos in cbo)
{
items.Add(0, "-------");
i = 1;
while (i <= 24)
{
cboId = i;
cboName = TimeSpan.FromHours(i).ToString("hh':'mm");
items.Add(cboId, cboName);
i++;
}
cbos.Tag = c;
cbos.DataSource = new BindingSource(items, null);
cbos.DisplayMember = "Value";
cbos.ValueMember = "Key";
items.Clear();
cbos.SelectedIndexChanged += new EventHandler(cboSelected);
c++;
}
}
public void cboSelected(object sender, EventArgs e)
{
ComboBox cb = ((ComboBox)sender);
int i_tmp;
int tg = Int32.Parse(cb.Tag.ToString());
if(tg % 2 == 0) //if is even
{
i_tmp= tg - 1;
}
else
{
i_tmp = tg + 1;
}
}
private void cmd_Save_Click(object sender, EventArgs e)
{
}
}
Solution:
public partial class workPlacePlan : Form
{
public workPlacePlan()
{
InitializeComponent();
}
private void workPlacePlan_Load(object sender, EventArgs e)
{
this.MaximumSize = this.Size;
this.MinimumSize = this.Size;
int cboId;
int i = 1;
string cboName; int c = 1;
var items = new Dictionary<int, string>();
ComboBox[] cbo = {
cbo_1_0, cbo_1_1, cbo_2_0, cbo_2_1, cbo_3_0, cbo_3_1, cbo_4_0, cbo_4_1, cbo_5_0, cbo_5_1, cbo_6_0, cbo_6_1,
cbo_13_0,cbo_13_1,cbo_14_0,cbo_14_1,cbo_15_0,cbo_15_1,cbo_16_0,cbo_16_1,cbo_17_0,cbo_17_1,cbo_18_0,cbo_18_1,
cbo_19_0,cbo_19_1
};
foreach(ComboBox cbos in cbo)
{
items.Add(0, "-------");
i = 1;
while (i <= 24)
{
cboId = i;
cboName = TimeSpan.FromHours(i).ToString("hh':'mm");
items.Add(cboId, cboName);
i++;
}
cbos.Tag = c;
cbos.DataSource = new BindingSource(items, null);
cbos.DisplayMember = "Value";
cbos.ValueMember = "Key";
cbos.SelectedIndex = 0;
items.Clear();
cbos.SelectedIndexChanged += new EventHandler(cboSelected);
c++;
}
}
public void cboSelected(object sender, EventArgs e)
{
ComboBox cb = ((ComboBox)sender);
int i_tmp;
int tg = Int32.Parse(cb.Tag.ToString());
int idx;
if(tg % 2 == 0) //if is even
{
i_tmp= tg - 1;
}
else
{
i_tmp = tg + 1;
}
//string y = cb.GetItemText(cb.SelectedItem);
//MessageBox.Show(y.ToString());
foreach (ComboBox cbt in panel1.Controls.OfType<ComboBox>()) {
if(Int32.Parse(cbt.Tag.ToString()) == Int32.Parse(i_tmp.ToString()))
{
idx = Int32.Parse(cbt.SelectedIndex.ToString());
cbt.SelectedIndex = idx;
MessageBox.Show(cbt.SelectedIndex.ToString());
}
}
}
private void cmd_Save_Click(object sender, EventArgs e)
{
}
}

Parsing list of string containing a delimiter to tree structure

So I have a list of strings like so:
var drinks = new List(){"Drinks", " * ", "Rum", "Captain Morgan", "Kraken", " * ", "Whiskey",
"Laphroaig"}
It needs to return the following:
*Drinks
*Drinks * Rum
*Drinks * Rum * Captain Morgan
*Drinks * Rum * Kraken
*Drinks * Whiskey
*Drinks * Whiskey * Laphroaig
So as seen, anytime a * is encountered, the next string would be treated as a child under the root. So here, Rum would fall under Drinks and Captain Morgan and Kraken would fall under Rum. Whiskey would fall under Drinks and Laphroaig would fall under whiskey.
I know it has to be some sort of tree structure and the only thing I have right now is this:
private static Drink GroupDrinks(List<string> drinkNames)
{
var drink = new Drink() { Children = new List<Drink>() };
foreach (var drinkName in drinkNames)
{
if (drinkName != "*")
{
drink.Name = drinkName;
drinkNames.RemoveAt(0);
}
else
{
drinkNames.RemoveAt(0);
drink.Children.Add(GroupDrinks(drinkNames));
}
}
return drink;
}
I figured I'd need to do some kind of recursion and maybe remove the character so it doesn't affect the next iteration but this clearly isn't working. Any tips would be great.
I am not sure if this code work for you but it is tested as your expected output:
Declaration:
List<Drink> lstdrink = new List<Drink>();
public List<FinalDrink> lstFinalDrink = new List<FinalDrink>();
Class:
public class FinalDrink
{
public string name { get; set; }
}
public class Drink
{
public string name { get; set; }
public int Tag { get; set; }
}
Set Up the Value:
public List<Drink> SetUpTheValue()
{
var drinks = new List<string> { "Drinks", " * ", "Rum", "Captain Morgan", "Kraken", " * ", "Whiskey", "Laphroaig" };
var repl = drinks.Select(s => s.Replace('*', ' ')).ToList();
string tag = string.Empty;
Drink drk = new Drink();
lstdrink = new List<Drink>();
for (int i = 0; i < repl.Count; i++)
{
if (i == 0)
{
drk = new Drink();
drk.name = repl[i];
drk.Tag = 1;
lstdrink.Add(drk);
tag = repl[i];
continue;
}
if (tag.Trim().Length == 0)
{
drk = new Drink();
drk.name = repl[i];
drk.Tag = 2;
lstdrink.Add(drk);
tag = repl[i];
continue;
}
if (repl[i].ToString().Trim().Length > 0)
{
drk = new Drink();
drk.name = repl[i];
drk.Tag = 0;
lstdrink.Add(drk);
tag = repl[i];
}
tag = repl[i];
}
return lstdrink;
}
Group Drinks:
public List<FinalDrink> GroupDrinks(List<Drink> drinkNames)
{
lstFinalDrink = new List<FinalDrink>();
FinalDrink fDrink = new FinalDrink();
var GetFirst = drinkNames.Where(x => x.Tag == 1).ToList();
fDrink.name = GetFirst[0].name.ToString();
lstFinalDrink.Add(fDrink);
var Content = drinkNames.Where(x => x.Tag != 1).ToList();
string itrVal = string.Empty;
int prev = 0;
string hcur = string.Empty;
for (int i = 0; i < Content.Count(); i++)
{
if (Content[i].Tag == 2)
{
hcur = GetFirst[0].name + " * " + Content[i].name;
fDrink = new FinalDrink();
itrVal = GetFirst[0].name + " * " + Content[i].name;
fDrink.name = itrVal;
lstFinalDrink.Add(fDrink);
prev = Content[i].Tag;
itrVal = string.Empty;
}
else
{
fDrink = new FinalDrink();
itrVal = hcur + " * " + Content[i].name;
fDrink.name = itrVal;
lstFinalDrink.Add(fDrink);
prev = Content[i].Tag;
itrVal = string.Empty;
}
}
return lstFinalDrink;
}
Execution:
private void button1_Click(object sender, EventArgs e)
{
if (SetUpTheValue().Count() > 0)
{
GroupDrinks(lstdrink);
}
}
The GroupDrinks return List<FinalDrink> this is the final result.
It is depend on you to modify the result
This Code will return the expected output as you added from above.

Displaying Particular Item On listView1_MouseClick

In Quize method I am passing qestions which contains set of all my Questions to be displayed using DisplayQuestion(),Question is my Class, Problem is that I am getting only First Question displayed, how can I get them displayed when i click on listviewItem if suppose questionscontains 10 Questions,than in listviewItem I have displayed numbers(1 2 3 4 5 ....10),when i click on each number how do i display that particular Questiondisplyed on click and if not clicked how all Questions displayed one by one using timer
public partial class GroupExmStart : Form
{
string[] randomQsn = new string[totQsn + 1]; //totQsn is the total number of question for e.g.10
public GroupExmStart(string GroupName, string DurationID)
{
InitializeComponent();
this.GrpID=GroupName;
TopiID=db.GetTopicIDForGroup(GrpID);
string[] conf = db.GetConfiguration(Convert.ToInt16(DurationID)).Split('|');
Question qsn = new Question();
var questions = qsn.Foo(TopiID, conf);
int z = Quiz(questions);
totQsn = Convert.ToInt16(conf[0]);
for (int kk = 1; kk <= totQsn; kk++)
{
ListViewItem lvi = new ListViewItem();
lvi.Text = kk.ToString();
listView1.Items.Add(lvi);
}
randomQsn = new string[totQsn + 1];
timer1.Interval = 1000; //1000ms = 1sec
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}
int Quiz(List<Question> questions)
{
foreach (Question question in questions)
{
DisplayQuestion(question);
}
return 0;
}
private void DisplayQuestion(Question question)
{
string Q = question.Text;
label5.Text = Q;
string OP1 = question.Option1;
string OP2 = question.Option2;
string OP3 = question.Option3;
string OP4 = question.Option4;
radioButton12.Text = OP1;
radioButton11.Text = OP2;
radioButton10.Text = OP3;
radioButton9.Text = OP4;
}
private void listView1_MouseClick(object sender, MouseEventArgs e)
{
if (randomQsn.GetLength(0) >= 0)
{
if (listView1.SelectedItems.Count > 0)
{
//here how should i get That particular Question so that i can display it
//something like this ? //Convert.ToInt16(listView1.SelectedItems[0].SubItems[0].Text)
DisplayQuestion(question);
}
}
}
private void timer1_Tick(object sender, EventArgs e)
{
tik++;
if (tik == 60)
{
label1.Text = (Convert.ToInt16(label1.Text) - 1).ToString();
tik = 0;
}
}
}
Thanks for any help in advance
The following is what you are looking for. You must grab the text of the list view item and use that as the index of the question.
if (listView1.SelectedItems.Count > 0)
{
var q = Convert.ToInt16(listView1.SelectedItems[0].Text);
var selectedQuestion = questions[q - 1];
DisplayQuestion(selectedQuestion);
}
In order for this to work, modify your constructor to the following:
private List<Question> questions;
public partial class GroupExmStart : Form
{
string[] randomQsn = new string[totQsn + 1]; //totQsn is the total number of question for e.g.10
public GroupExmStart(string GroupName, string DurationID)
{
InitializeComponent();
this.GrpID=GroupName;
TopiID=db.GetTopicIDForGroup(GrpID);
string[] conf = db.GetConfiguration(Convert.ToInt16(DurationID)).Split('|');
Question qsn = new Question();
/// THIS IS MODIFIED //
questions = qsn.Foo(TopiID, conf);
int z = Quiz(questions);
totQsn = Convert.ToInt16(conf[0]);
for (int kk = 1; kk <= totQsn; kk++)
{
ListViewItem lvi = new ListViewItem();
lvi.Text = kk.ToString();
listView1.Items.Add(lvi);
}
randomQsn = new string[totQsn + 1];
timer1.Interval = 1000; //1000ms = 1sec
timer1.Tick += new EventHandler(timer1_Tick);
timer1.Start();
}

Leave Event is called twice in case of deletion

I have the below code
public void panel_item_collections_Click(object sender, EventArgs e)
{
TextBox[] textbox_item_array = new TextBox[5];
item_textbox.Add(textbox_item_array);
textbox_item_array[0] = new TextBox();
textbox_item_array[0].Width = label_item_code.Width;
textbox_item_array[0].Height = 26;
textbox_item_array[0].Font = print_font_default;
textbox_item_array[0].Location = new Point(label_item_code.Location.X, 45 + (20 * row_count));
textbox_item_array[0].Name = string.Concat("item_code", row_count.ToString());
panel_item_collections.Controls.Add(textbox_item_array[0]);
textbox_item_array[0].Leave += new EventHandler(dynamic_text_item_code_Leave);
textbox_item_array[1] = new TextBox();
textbox_item_array[1].Width = label_item_descrition.Width;
textbox_item_array[1].Font = textbox_item_array[0].Font;
textbox_item_array[1].Location = new Point(label_item_descrition.Location.X, textbox_item_array[0].Location.Y);
textbox_item_array[1].Name = string.Concat("item_description", row_count.ToString());
panel_item_collections.Controls.Add(textbox_item_array[1]);
textbox_item_array[2] = new TextBox();
textbox_item_array[2].Width = label_item_price.Width;
textbox_item_array[2].Font = textbox_item_array[0].Font;
textbox_item_array[2].Location = new Point(label_item_price.Location.X, textbox_item_array[0].Location.Y);
textbox_item_array[2].Name = string.Concat("item_price", row_count.ToString());
panel_item_collections.Controls.Add(textbox_item_array[2]);
textbox_item_array[3] = new TextBox();
textbox_item_array[3].Width = label_item_quantity.Width;
textbox_item_array[3].Font = textbox_item_array[0].Font;
textbox_item_array[3].Location = new Point(label_item_quantity.Location.X, textbox_item_array[0].Location.Y);
textbox_item_array[3].Name = string.Concat("item_quantity", row_count.ToString());
panel_item_collections.Controls.Add(textbox_item_array[3]);
textbox_item_array[4] = new TextBox();
textbox_item_array[4].Width = label_item_total.Width;
textbox_item_array[4].Font = textbox_item_array[0].Font;
textbox_item_array[4].Location = new Point(label_item_total.Location.X, textbox_item_array[0].Location.Y);
textbox_item_array[4].Name = string.Concat("item_total", row_count.ToString());
panel_item_collections.Controls.Add(textbox_item_array[4]);
row_count++;
}
Now, here is the leave event handler:
void dynamic_text_item_code_Leave(object sender, EventArgs e)
{
//MessageBox.Show(((Control)sender).Name.Substring(((Control)sender).Name.Length - 1, 1));
int i;
string name_textbox = ((Control)sender).Name;
i = System.Convert.ToInt32(name_textbox.Substring(name_textbox.Length - 1, 1));
//MessageBox.Show(i.ToString());
//i--;
TextBox[] textbox_item_array = new TextBox[5];
textbox_item_array = (TextBox[])(item_textbox[i]);
double item_total;
Item item = new Item();
if (long.TryParse(textbox_item_array[0].Text, out item.item_code) == true)
{
if (item.get_item() == 0)
{
textbox_item_array[1].Text = item.item_details;
textbox_item_array[2].Text = item.sell_price.ToString();
textbox_item_array[3].Text = "1";
item_total = System.Convert.ToInt32(textbox_item_array[3].Text) * item.sell_price;
textbox_item_array[4].Text = item_total.ToString();
}
}
else
{
//TextBox[] textbox_item_array = new TextBox[5];
textbox_item_array = (TextBox[])(item_textbox[item_textbox.Count - 1]);
panel_item_collections.Controls.Remove(textbox_item_array[0]);
panel_item_collections.Controls.Remove(textbox_item_array[1]);
panel_item_collections.Controls.Remove(textbox_item_array[2]);
panel_item_collections.Controls.Remove(textbox_item_array[3]);
panel_item_collections.Controls.Remove(textbox_item_array[4]);
item_textbox.RemoveAt((item_textbox.Count - 1));
row_count--;
}
}
Now, the problem is like this:
If the user leave the textbox blank, the row will be deleted. The strange problem is:
If press tab, it will execute the leave event handler twice. It means it will try to delete the same textbox twice and this will create problem. Can any one help me how to avoid this double calling?
Thanks
I want to add more: here is exactly what is happening:
Now, I will give exactly how it is executed:
void dynamic_text_item_code_Leave(object sender, EventArgs e)
{
//MessageBox.Show(((Control)sender).Name.Substring(((Control)sender).Name.Length - 1, 1));
int i;
string name_textbox = ((Control)sender).Name;
i = System.Convert.ToInt32(name_textbox.Substring(name_textbox.Length - 1, 1));
//MessageBox.Show(i.ToString());
//i--;
TextBox[] textbox_item_array = new TextBox[5];
textbox_item_array = (TextBox[])(item_textbox[i]);
double item_total;
Item item = new Item();
if (long.TryParse(textbox_item_array[0].Text, out item.item_code) == true)
{
if (item.get_item() == 0)
{
textbox_item_array[1].Text = item.item_details;
textbox_item_array[2].Text = item.sell_price.ToString();
textbox_item_array[3].Text = "1";
item_total = System.Convert.ToInt32(textbox_item_array[3].Text) * item.sell_price;
textbox_item_array[4].Text = item_total.ToString();
}
}
else
{
//TextBox[] textbox_item_array = new TextBox[5];
textbox_item_array = (TextBox[])(item_textbox[item_textbox.Count - 1]);
panel_item_collections.Controls.Remove(textbox_item_array[0]);
After that, it calls the same function
void dynamic_text_item_code_Leave(object sender, EventArgs e)
{
//MessageBox.Show(((Control)sender).Name.Substring(((Control)sender).Name.Length - 1, 1));
int i;
string name_textbox = ((Control)sender).Name;
i = System.Convert.ToInt32(name_textbox.Substring(name_textbox.Length - 1, 1));
//MessageBox.Show(i.ToString());
//i--;
TextBox[] textbox_item_array = new TextBox[5];
textbox_item_array = (TextBox[])(item_textbox[i]);
double item_total;
Item item = new Item();
if (long.TryParse(textbox_item_array[0].Text, out item.item_code) == true)
{
if (item.get_item() == 0)
{
textbox_item_array[1].Text = item.item_details;
textbox_item_array[2].Text = item.sell_price.ToString();
textbox_item_array[3].Text = "1";
item_total = System.Convert.ToInt32(textbox_item_array[3].Text) * item.sell_price;
textbox_item_array[4].Text = item_total.ToString();
}
}
else
{
//TextBox[] textbox_item_array = new TextBox[5];
textbox_item_array = (TextBox[])(item_textbox[item_textbox.Count - 1]);
panel_item_collections.Controls.Remove(textbox_item_array[0]);
panel_item_collections.Controls.Remove(textbox_item_array[1]);
panel_item_collections.Controls.Remove(textbox_item_array[2]);
panel_item_collections.Controls.Remove(textbox_item_array[3]);
panel_item_collections.Controls.Remove(textbox_item_array[4]);
item_textbox.RemoveAt((item_textbox.Count - 1));
row_count--;
}
}
Then it continues here
panel_item_collections.Controls.Remove(textbox_item_array[1]);
panel_item_collections.Controls.Remove(textbox_item_array[2]);
panel_item_collections.Controls.Remove(textbox_item_array[3]);
panel_item_collections.Controls.Remove(textbox_item_array[4]);
item_textbox.RemoveAt((item_textbox.Count - 1));
row_count--;
}
}
So, why it executes once it get to the remove
Are you sure, you don't use this line twice in another part of code?
textbox_item_array[0].Leave += new EventHandler(dynamic_text_item_code_Leave);
If not I suppose you hooks dynamic_text_item_code_Leave to one another control.
EDIT
You can also to protect by adding this code:
if (textbox_item_array[0].Leave != null)
textbox_item_array[0].Leave += new EventHandler(dynamic_text_item_code_Leave);

Categories

Resources