У меня есть сетка данных, которая содержит разные записи и соответствующий таймер в каждой строке, мне нужно, чтобы, когда таймер достигнет 0, строка была удалена и перенесена в другую сетку данных, но я получаю сообщение об ошибке, которое не может быть удалить строку во время работы foreach, но, поскольку я работаю с таймером, неизбежно не запускать foreach, поскольку он работает постоянно, есть ли альтернатива, чтобы удалить строку, где таймер имеет значение 0, и изменить ее на другую сетку данных?
public Form1()
{
InitializeComponent();
dtStopwatches.Columns.Add("ID", typeof(int));
dtStopwatches.Columns.Add("Nombre", typeof(string));
dtStopwatches.Columns.Add("Tiempo Restante", typeof(string));
dataGridView1.DataSource = dtStopwatches;
foreach (string buttonName in new string[] { "Pausar/Reanudar", "Reset", "Restart" })
{
DataGridViewButtonColumn colTemp = new DataGridViewButtonColumn();
colTemp.Name = buttonName + "Col";
colTemp.HeaderText = buttonName;
colTemp.Width = 100;
dataGridView1.Columns.Add(colTemp);
}
timer1.Tick += (timer1_Tick);
timer1.Interval = 1000;
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e) <----- AQUÍ EL PROBLEMA
{
timer1.Stop();
foreach (DataRow dRow in dtStopwatches.Rows)
{
int hours = int.Parse((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"hh")) - 23; // <----- ASIGNACIÓN DE HORAS (24 - horas deseadas)
int mins = int.Parse((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"mm")) - 59; // <----- ASIGNACIÓN DE MINUTOS (60 - minutos deseados)
int secs = int.Parse(((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"ss"))) - 55; // <------ ASIGNACIÓN DE SEGUNDOS (60 - segundos deseados)
if (hours == 0 && mins == 0 && secs == 0)
{
swDct[(int)dRow["ID"]].Stop();
//dtStopwatches.Rows.Remove(dRow); **<--- en este punto debería eliminarse el row**
}
string temp = hours.ToString("00") + ":"
+ mins.ToString("00") + ":"
+ secs.ToString("00");
dRow["Tiempo Restante"] = temp;
}
timer1.Start();
}
private void BtnAddStopwatch_Click_1(object sender, EventArgs e)
{
dtStopwatches.Rows.Add(nextID, txt_nombre.Text, "00:00:00");
swDct.Add(nextID, new Stopwatch());
nextID++;
Stopwatch swTemp = swDct[(int)dataGridView1.Rows[temp].Cells["ID"].Value];
swTemp.Start();
temp++;
}
private void DataGridView1_CellClick_1(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex > -1)
{
Stopwatch swTemp = swDct[(int)dataGridView1.Rows[e.RowIndex].Cells["ID"].Value];
switch (dataGridView1.Columns[e.ColumnIndex].HeaderText)
{
case "Pausar/Reanudar":
if (swDct[(int)dataGridView1.Rows[e.RowIndex].Cells["ID"].Value].IsRunning == true)
{ swTemp.Stop();}
else{
swTemp.Start();}
break;
case "Reset":
swTemp.Reset();
break;
case "Restart":
swTemp.Restart();
break;
}
}
}
Хороший dГ - в
Используя цикл for вместо foreach оно ты было бы должно функционировать так:
for(int i = 0; i == 0; i++)
{
DataRow drow = dtStopwatches.Rows[i];
int hours = int.Parse((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"hh")) - 23; // <----- ASIGNACIÓN DE HORAS (24 - horas deseadas)
int mins = int.Parse((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"mm")) - 59; // <----- ASIGNACIÓN DE MINUTOS (60 - minutos deseados)
int secs = int.Parse(((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"ss"))) - 55; // <------ ASIGNACIÓN DE SEGUNDOS (60 - segundos deseados)
if (hours == 0 && mins == 0 && secs == 0)
{
swDct[(int)dRow["ID"]].Stop();
dtStopwatches.Rows.RemoveAt(i);//aca lo eliminas por ID
}
string temp = hours.ToString("00") + ":"
+ mins.ToString("00") + ":"
+ secs.ToString("00");
dRow["Tiempo Restante"] = temp;
}
Есть то, что faltarГ, - чтобы контролировать, является темой, когда мое количество rows будет равно моему счетчику, есть tendrГ-эксперт, который должен возобновлять счетчик, Я надеюсь, что он служит.
foreach
оно не функционирует, так как ты изменяешь ее colecciГіn, удалив элемент. tГ©cnica обычный состоит в том, чтобы реализовывать ее один for
в обратном чувстве.
for(int i = dtStopwatches.Rows.Count-1; i == 0; i--)
{
DataRow drow = dtStopwatches.Rows[i];
int hours = int.Parse((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"hh")) - 23; // <----- ASIGNACIÓN DE HORAS (24 - horas deseadas)
int mins = int.Parse((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"mm")) - 59; // <----- ASIGNACIÓN DE MINUTOS (60 - minutos deseados)
int secs = int.Parse(((TimeSpan.Parse(swDct[(int)dRow["ID"]].Elapsed.ToString()) - TimeSpan.Parse(1.ToString())).ToString(@"ss"))) - 55; // <------ ASIGNACIÓN DE SEGUNDOS (60 - segundos deseados)
if (hours == 0 && mins == 0 && secs == 0)
{
swDct[(int)dRow["ID"]].Stop();
dtStopwatches.Rows.RemoveAt(i); //Eliminamos la fila según el ID
}
string temp = hours.ToString("00") + ":"
+ mins.ToString("00") + ":"
+ secs.ToString("00");
dRow["Tiempo Restante"] = temp;
}