CanYou8 发表于 2015-12-15 16:55:00

C1FlexGrid行编辑相关事件请教

C1.WPF.FlexGrid 用的不多,事件用得更少了。有个问题尝试了很久也没有思路,请版主指点下。
需求是这样的:
1.按回车键,自动跳到下一行可编辑单元格,即光标自动定位到下一行去(假定C1.WPF.FlexGrid 只有1列是可编辑的)
2.在跳到下一行之前,调用自定义方法检测输入的合法性;若不合法,弹出提示并留在原单元格(光标位置不变,仍在原来的可编辑单元格中)
请问:要用哪些事件,或事件组合来实现这些功能?

Alice 发表于 2015-12-15 17:37:00

回复 1楼CanYou8的帖子

您好。
在之前的帖子里我们讨论过这个问题,也提供了基本思路和简单的代码演示。
PreviewKeyDown事件可以用来检测Enter键的按下,也可以用来处理您的相关逻辑。
之前的帖子参考:
http://gcdn.gcpowertools.com.cn/showtopic-19807.html
我不太理解您是哪里没有思路,或是哪一步出现问题?

CanYou8 发表于 2015-12-16 11:53:00

如下的代码实现,有两个问题:
1.刚刚编辑的数据,回车跳到下一行后失效(会变为旧的数据)
2.若当前为第n行,调试时会跳到n+1行并是单元格编辑状态,实现了想要的效果;但非调试时会跳到第n+2行,单元格也不是编辑状态
请帮忙看下
      //捕捉键盘按下事件
      private void _processFlowFlexGrid_PreviewKeyDown(object sender, KeyEventArgs e)
      {
            try
            {
                var grid = sender as C1FlexGrid;
                if (e.Key != Key.Enter || grid == null) return;

                //当前单元格的坐标位置
                int row = grid.Selection.Row;
                int col = grid.Selection.Column;

                //提交本次编辑
                grid.FinishEditing(true);

                //参数校验
                bool checkParamResult = true;
                var model = (FlowModel)grid.SelectedItem;
                if (null != model && !string.IsNullOrEmpty(model.ParamValue))
                {
                  checkParamResult = CheckParam(model);
                }

                if (checkParamResult) //通过
                {
                  e.Handled = true;

                  //下一行的序号
                  int newRowIndex = row + 1;
                  newRowIndex = grid.Rows.Count > newRowIndex ? newRowIndex : row;
                  //滚动到将要编辑的下个单元格
                  grid.ScrollIntoView(newRowIndex, col);
                  grid.StartEditing(true, newRowIndex, col);
                }
                else //未通过
                {
                  e.Handled = true;
                  grid.StartEditing(true, row, col);
                }
            }
            catch (Exception ex)
            {
               MessageBox.Show(ex.Message);
            }
      }

Alice 发表于 2015-12-16 14:18:00

回复 3楼CanYou8的帖子

谢谢您的反馈。
代码我们收到了,测试后给您反馈。

Alice 发表于 2015-12-16 15:46:00

回复 3楼CanYou8的帖子

第一个问题没有重现。
第二个问题是由于C1FlexGrid默认的Enter会执行MoveToNextRow的操作,然后在事件里又执行了一次,效果叠加。
可以将_flexFilter.KeyActionEnter = KeyAction.None;
将默认自带的回车键处理禁用。

CanYou8 发表于 2015-12-16 17:38:00

第一个问题我再看下;还有个问题:回车后,将下一行单元格设为可编辑状态,但光标没有定位在单元格里,请问如何定位光标到下一行的单元格里面?

Alice 发表于 2015-12-17 09:35:00

回复 6楼CanYou8的帖子

您好。
我测试 grid.StartEditing(true, newRowIndex, col);方法可以使得单元格进入编辑状态。
调用方法后获取ActiveEditor不为null

CanYou8 发表于 2015-12-18 11:52:00

为了兼顾回车即跳入下一个可编辑单元格,和不按回车用鼠标点击进入下一个可编辑单元格,我采用了两个事件,代码如下:
      //捕捉键盘按下事件
      private void _flexGrid_PreviewKeyDown(object sender, KeyEventArgs e)
      {
            if (e.Key != Key.Enter) return;
            try
            {
                var grid = sender as C1FlexGrid;
                if (grid == null) return;

                //去掉C1FlexGrid默认的Enter动作
                __flexGrid.KeyActionEnter = KeyAction.None;
                e.Handled = true;
                //当前单元格的坐标位置
                int row = grid.Selection.Row;
                int col = grid.Selection.Column;
                //下一行的序号
                int nextRowIndex = row + 1;
                nextRowIndex = grid.Rows.Count > nextRowIndex ? nextRowIndex : row;

                //滚动到将要编辑的下个单元格
                grid.ScrollIntoView(nextRowIndex, col);
                //进入单元格的编辑状态
                grid.StartEditing(true, nextRowIndex, col);

                //MessageBox.Show(__flexGrid.ActiveEditor == null ? "ActiveEditor是Null" : "ActiveEditor非Null");//运行到此处则会弹出"ActiveEditor非Null"
            }
            catch (Exception ex)
            {
            }
      }

      //捕捉单元格结束编辑事件
      private void _flexGrid_CellEditEnding(object sender, CellEditEventArgs e)
      {
            //参数校验
            bool checkParamResult = true;
            var model = (FlowModel)e.Editor.DataContext;
            if (null != model && !string.IsNullOrEmpty(model.ParamValue))
            {
                checkParamResult = CheckParam(model); //调用校验方法,返回校验结果
            }

            e.Cancel = !checkParamResult;
      }

问题: 1.在PreviewKeyDown事件的结尾,加了弹出框来测试“ActiveEditor”属性,弹出的结果均是"ActiveEditor非Null",而此时焦点也会在单元格里面;如果注释了此处弹出框代码,会发现焦点在下一个单元格里出现,之后则很快消失,虽然单元格是可编辑状态,但焦点不在,仍然不可以直接编辑。如何定位焦点到下一个单元格?
2. CellEditEnding事件的目的,是来判断输入的合法性;如果校验不通过,不可以跳到其他单元格,而且焦点也需要锁定在此单元格;校验通过就继续。现在的这种实现,无论通过还是不通过,都会跳到其他单元格。如何实现这种需求?

Alice 发表于 2015-12-18 13:56:00

回复 8楼CanYou8的帖子

我正在测试您的代码,测试完给您反馈。

Alice 发表于 2015-12-18 17:48:00

回复 8楼CanYou8的帖子

第一个问题重现了,我们需要看看出现问题的原因,再给您反馈。
第二个问题,可以在CellEditEnding验证之后,回到PreviewKeyDown事件时,进行判断,然后处理是否移动到下一行。您可以参考下附件的代码,当然还有其他的方案,这个仅供参考。
页: [1] 2
查看完整版本: C1FlexGrid行编辑相关事件请教