none
DataGridView中如何对单元格焦点进行控制? RRS feed

  • 问题

  • 操作无效,原因是它导致对 SetCurrentCellAddressCore 函数的可重入调用。

    private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
    {
         if (e.ColumnIndex == dataGridView1.Columns[Column2.Name].Index)//如果焦点进入第二个单元格
        {
           dataGridView1.CurrentCell = dataGridView1.Rows[e.RowIndex].Cells[Column4.Name];//当前编辑单元格为第四个单元格
        }         
    }

    我想达到的效果是当我完成对第一单元格的编辑后切换焦点到第四单元格,但我用上面的代码来切换焦点的时候,却报出"操作无效,原因是它导致对 SetCurrentCellAddressCore 函数的可重入调用。"。这个问题在其他地方找了很久没有找到合适的解决方法,有哪位高手做过关于datagridview的焦点控制的请讲讲你们的经验或者解决这个问题的方法。谢谢!

    2010年5月9日 16:14

答案

  • 你好!

         通常是你的代码中存在死循环,当你设置dataGridView1.CurrentCell属性的时候又会再次触发CellEnter事件,所以出现了死循环!

         你检查一下相关问题!


    周雪峰
    2010年5月10日 1:32
    版主
  •  private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
          if (e.ColumnIndex ==1)//如果焦点进入第二个单元格
          {
            dataGridView1.CurrentRow.Cells[1].Selected =false;
            dataGridView1.CurrentRow.Cells[3].Selected=true;//当前编辑单元格为第四个单元格
          }     
    
        }
    

    努力+方法=成功
    2010年5月10日 1:47
  • 你好,

    你可以重写datagridview SetCurrentCellAddressCore 方法 SetSelectedCellCore 方法。

     

    具体实现请参考下面的FAQ:

    1.如何限制用户将焦点设置到特定的单元格上?

     

    Best regards,

    Ling Wang


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    2010年5月12日 4:10
    版主
  • 谢谢大家关注,问题已经解决了,用了个比较笨的方法,重写了datagridview的事件:ProcessCmdKey

    代码如下:实现功能,随意跳单元格,将enter替换为tab

    public class FoucesChangeInfo
      {
        int _oldColumnsIndex;
        /// <summary>
        /// 当前焦点的列号
        /// </summary>
        public int OldColumnsIndex
        {
          get { return _oldColumnsIndex; }
          set { _oldColumnsIndex = value; }
        }
        int _newColumnsIndex;
        /// <summary>
        /// 需要跳到的焦点的列号
        /// </summary>
        public int NewColumnsIndex
        {
          get { return _newColumnsIndex; }
          set { _newColumnsIndex = value; }
        }
        bool _isSameRowIndex;
        /// <summary>
        /// 是否需要跳到下一行
        /// </summary>
        public bool IsSameRowIndex
        {
          get { return _isSameRowIndex; }
          set { _isSameRowIndex = value; }
        }
        public FoucesChangeInfo()
        { }
        /// <summary>
        /// 焦点切换
        /// </summary>
        /// <param name="oldColumnsIndex">当前焦点的列号</param>
        /// <param name="newColumnsIndex">需要跳到的焦点的列号</param>
        /// <param name="isSameRowIndex">是否需要跳到下一行</param>
        public FoucesChangeInfo(int oldColumnsIndex,int newColumnsIndex,bool isSameRowIndex)
        {
          _oldColumnsIndex = oldColumnsIndex;
          _newColumnsIndex = newColumnsIndex;
          _isSameRowIndex = isSameRowIndex;
        }
    
    public public partial class AET_DataGridView : DataGridView
    {
        bool _enterToTab = true;
        /// <summary>
        /// 是否要将enter转换为tab
        /// </summary>
        public bool EnterToTab
        {
          get { return _enterToTab; }
          set { _enterToTab = value; }
        }
    
    List<FoucesChangeInfo> _l_fci = null;
        /// <summary>
        /// 需要跳动焦点的信息
        /// </summary>
        public List<FoucesChangeInfo> L_fci
        {
          get { return _l_fci; }
          set { _l_fci = value; }
        }
    
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
          KeyEventArgs kea = new KeyEventArgs(keyData);
          bool isProcess = false;
          if (kea.KeyCode == Keys.Tab || (kea.KeyCode == Keys.Enter && EnterToTab))
          {
            if (L_fci != null)
            {
              for (int i = 0; i < L_fci.Count; i++)
              {
                if (this.CurrentCellAddress.X == L_fci[i].OldColumnsIndex && L_fci[i].IsSameRowIndex)
                {
                  if (this.CurrentCellAddress.Y + 1 != this.Rows.Count)
                  {
                    this.Rows[this.CurrentCellAddress.Y + 1].Cells[L_fci[i].NewColumnsIndex].Selected = true;
                    isProcess = true;
                  }
                  break;
                }
                else if (this.CurrentCellAddress.X == L_fci[i].OldColumnsIndex && !L_fci[i].IsSameRowIndex)
                {
                  this.Rows[this.CurrentCellAddress.Y].Cells[L_fci[i].NewColumnsIndex].Selected = true;
                  isProcess = true;
                  break;
                }
              }
              if (isProcess)
              {
                return true;
              }
              else
              {
                if (kea.KeyCode == Keys.Enter && EnterToTab)
                {
                  SendKeys.Send("{Tab}");
                  return true;
                }
                else
                {
                  return base.ProcessCmdKey(ref  msg, keyData);
                }
              }
            }
            else
            {
              if (kea.KeyCode == Keys.Enter && EnterToTab)
              {
                SendKeys.Send("{Tab}");
                return true;
              }
              else
              {
                return base.ProcessCmdKey(ref  msg, keyData);
              }
            }
          }
          else
          {
            return base.ProcessCmdKey(ref  msg, keyData);
          }
        }
    }
    • 已标记为答案 楓の戀 2010年5月16日 5:09
    2010年5月14日 10:24

全部回复

  • 你好!

         通常是你的代码中存在死循环,当你设置dataGridView1.CurrentCell属性的时候又会再次触发CellEnter事件,所以出现了死循环!

         你检查一下相关问题!


    周雪峰
    2010年5月10日 1:32
    版主
  •  private void dataGridView1_CellEnter(object sender, DataGridViewCellEventArgs e)
        {
          if (e.ColumnIndex ==1)//如果焦点进入第二个单元格
          {
            dataGridView1.CurrentRow.Cells[1].Selected =false;
            dataGridView1.CurrentRow.Cells[3].Selected=true;//当前编辑单元格为第四个单元格
          }     
    
        }
    

    努力+方法=成功
    2010年5月10日 1:47
  • 谢谢,这个是问题的根源,请问您在实际的编程中有解决过关于这个datagridview的焦点处理的问题吗?

    2010年5月10日 8:20
  • 谢谢你的关注,这个我试过了,当我执行完这个操作以后的情况是单元格1上面有个虚线方框,单元格3的颜色变为选中颜色,而单元格3不能进入编辑状态

    2010年5月10日 8:23
  • 你好,

    你可以重写datagridview SetCurrentCellAddressCore 方法 SetSelectedCellCore 方法。

     

    具体实现请参考下面的FAQ:

    1.如何限制用户将焦点设置到特定的单元格上?

     

    Best regards,

    Ling Wang


    Please remember to click “Mark as Answer” on the post that helps you, and to click “Unmark as Answer” if a marked post does not actually answer your question. This can be beneficial to other community members reading the thread.
    2010年5月12日 4:10
    版主
  •             if (dataGridView1.CurrentCellAddress.X == 3 || dataGridView1.CurrentCellAddress.X == 1||dataGridView1.CurrentCellAddress.X==5)用这种方式来判断当前获得焦点的是第几格,上面这句话是当第三或第一或第五格获得焦点。
    can you help me?
    2010年5月13日 2:46
  • 谢谢大家关注,问题已经解决了,用了个比较笨的方法,重写了datagridview的事件:ProcessCmdKey

    代码如下:实现功能,随意跳单元格,将enter替换为tab

    public class FoucesChangeInfo
      {
        int _oldColumnsIndex;
        /// <summary>
        /// 当前焦点的列号
        /// </summary>
        public int OldColumnsIndex
        {
          get { return _oldColumnsIndex; }
          set { _oldColumnsIndex = value; }
        }
        int _newColumnsIndex;
        /// <summary>
        /// 需要跳到的焦点的列号
        /// </summary>
        public int NewColumnsIndex
        {
          get { return _newColumnsIndex; }
          set { _newColumnsIndex = value; }
        }
        bool _isSameRowIndex;
        /// <summary>
        /// 是否需要跳到下一行
        /// </summary>
        public bool IsSameRowIndex
        {
          get { return _isSameRowIndex; }
          set { _isSameRowIndex = value; }
        }
        public FoucesChangeInfo()
        { }
        /// <summary>
        /// 焦点切换
        /// </summary>
        /// <param name="oldColumnsIndex">当前焦点的列号</param>
        /// <param name="newColumnsIndex">需要跳到的焦点的列号</param>
        /// <param name="isSameRowIndex">是否需要跳到下一行</param>
        public FoucesChangeInfo(int oldColumnsIndex,int newColumnsIndex,bool isSameRowIndex)
        {
          _oldColumnsIndex = oldColumnsIndex;
          _newColumnsIndex = newColumnsIndex;
          _isSameRowIndex = isSameRowIndex;
        }
    
    public public partial class AET_DataGridView : DataGridView
    {
        bool _enterToTab = true;
        /// <summary>
        /// 是否要将enter转换为tab
        /// </summary>
        public bool EnterToTab
        {
          get { return _enterToTab; }
          set { _enterToTab = value; }
        }
    
    List<FoucesChangeInfo> _l_fci = null;
        /// <summary>
        /// 需要跳动焦点的信息
        /// </summary>
        public List<FoucesChangeInfo> L_fci
        {
          get { return _l_fci; }
          set { _l_fci = value; }
        }
    
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
          KeyEventArgs kea = new KeyEventArgs(keyData);
          bool isProcess = false;
          if (kea.KeyCode == Keys.Tab || (kea.KeyCode == Keys.Enter && EnterToTab))
          {
            if (L_fci != null)
            {
              for (int i = 0; i < L_fci.Count; i++)
              {
                if (this.CurrentCellAddress.X == L_fci[i].OldColumnsIndex && L_fci[i].IsSameRowIndex)
                {
                  if (this.CurrentCellAddress.Y + 1 != this.Rows.Count)
                  {
                    this.Rows[this.CurrentCellAddress.Y + 1].Cells[L_fci[i].NewColumnsIndex].Selected = true;
                    isProcess = true;
                  }
                  break;
                }
                else if (this.CurrentCellAddress.X == L_fci[i].OldColumnsIndex && !L_fci[i].IsSameRowIndex)
                {
                  this.Rows[this.CurrentCellAddress.Y].Cells[L_fci[i].NewColumnsIndex].Selected = true;
                  isProcess = true;
                  break;
                }
              }
              if (isProcess)
              {
                return true;
              }
              else
              {
                if (kea.KeyCode == Keys.Enter && EnterToTab)
                {
                  SendKeys.Send("{Tab}");
                  return true;
                }
                else
                {
                  return base.ProcessCmdKey(ref  msg, keyData);
                }
              }
            }
            else
            {
              if (kea.KeyCode == Keys.Enter && EnterToTab)
              {
                SendKeys.Send("{Tab}");
                return true;
              }
              else
              {
                return base.ProcessCmdKey(ref  msg, keyData);
              }
            }
          }
          else
          {
            return base.ProcessCmdKey(ref  msg, keyData);
          }
        }
    }
    • 已标记为答案 楓の戀 2010年5月16日 5:09
    2010年5月14日 10:24