user366312
user366312

Reputation: 16896

Setting focus to a DataGridView row

The following source code is intended to set focus to the immediately previous row of a deleted row.

enter image description here

Suppose I want to delete an unwanted word dddddddd from the database. When I press the Delete button, I want the word cynosure to be focused and placed at the top of the DataGridView which is not the case right now.

enter image description here

Right now, it is displayed at the bottom.

enter image description here

Source Code

    void SetFocusToWord(Word concernedWord)
    {
        if (concernedWord != null)
        {
            int index = 0;
            foreach (DataGridViewRow r in dataGridView1.Rows)
            {
                Word item = r.Tag as Word;

                if (concernedWord.Name == item.Name)
                {
                    dataGridView1.Focus();
                    dataGridView1.CurrentCell = dataGridView1.Rows[index].Cells[0];

                    break;
                }

                index++;
            }
        }
    } 

private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                if (dataGridView1.SelectedRows.Count > 0)
                {
                    int selectionIndex = dataGridView1.SelectedRows[0].Index;

                    foreach (DataGridViewRow r in dataGridView1.SelectedRows)
                    {
                        Word c = r.Tag as Word;

                        if (c != null)
                        {
                            _wordDatabase.Delete(c);
                        }
                    }

                    LoadToDataGridView();

                    if(selectionIndex > 0)
                    {
                        selectionIndex = selectionIndex - 1;
                    }

                    Word item = dataGridView1.Rows[selectionIndex].Tag as Word;

                    SetFocusToWord(item);
                }
                else
                {
                    throw new Exception(SelectionErrorMessages.GetErrorMessageFor(typeof(Word)));
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        } 

    void LoadToDataGridView()
    {
        dataGridView1.Rows.Clear();

        List<Word> items = (List<Word>)_wordDatabase.Get();

        if (items != null)
        {
            if (items.Count > 0)
            {
                int i = 0;
                foreach (Word c in items)
                {
                    dataGridView1.Rows.Add(c.Name, c.Hint);
                    dataGridView1.Rows[i].Tag = c;
                    ++i;
                }
            }
        }
    } 

Upvotes: 1

Views: 74

Answers (2)

LarsTech
LarsTech

Reputation: 81610

Reloading the database seems like an unnecessary step.

Based on how you want the grid to behave, try using code like this:

if (dataGridView1.SelectedRows.Count > 0) {
  int selectIndex = dataGridView1.SelectedRows[0].Index;
  dataGridView1.Rows.RemoveAt(selectIndex);
  if (selectIndex > 0) {
    dataGridView1.ClearSelection();
    dataGridView1.Rows[selectIndex - 1].Selected = true;
    dataGridView1.FirstDisplayedScrollingRowIndex = selectIndex - 1;
  }
}

Upvotes: 1

Kostya
Kostya

Reputation: 849

Poor performance and abundance of unnecessary code in your project are the result of you not using winforms binding properly. I suggest you start utilizing control's BindingContext and BindingSource accordingly. This should solve most of your problems.

For further details on winforms binding I recommend this docs.

Upvotes: 0

Related Questions