sxyweiren 发表于 2015-12-21 16:20:00

关于MultiRow的自定义单元格的问题

最近开始接触MultiRow,发现8.0跟4.0甚至以前版本区别稍微有些大。因此有通过自定义控件的方式来减小差异的想法。

但是,现在提供的Demo里面好像没有对InputMan类型的单元格进行重构的例子。

请问,能不能提供个例子参考下。

初步构想是这样的:

1,由于单元格处于编辑状态的时候,按下回车键以及左右键甚至F1-F12不会触发MultiRow的KeyPreview事件,因此想要通过自定义单元格呼出GcMultiRow的这些事件。

2,由于GcDate以及GcNumber类型的控件,原有的IvalidateRange以及IvalidateValue事件已经没有了。并且值的还原动作也不一样了。所以想要在封装的单元格里面增加这些动作。

3,Template的动态重构:由于Mr4.0的复数行表示与Mr8.0的复数行表示差异过于大,所以预定对Template进行动态重构,在Template的值发生变更的时候,动态的读入设定的Template并对该Template进行初期化
    说明:Mr4.0里面,如果每条数据复数行显示的时候(第一行5列第二行7列),可以通过Mr(1,5,1)来定位到第二行的第二小行的第六列
             Mr8.0里面,由于不支持 上面的三个数字来定位单元格的形式,所以代码要通过数单元格的形式来实现。但是对于不规则模板,就比较麻烦了。比如:Mr(1,10)来定位同样的单元格。

4,如果上面的构思3实现不了的话,预计通过循环单元格的形式来吧上面的单元格在BaseControl里面给数出来。这样需要把MultiRow进行下简单的封装

5,由于GcDate以及GcNumber类型的控件,如果通过Source赋予一个超过最大值的一个值的时候,Mr8.0里面会抛出一个异常,而Mr4.0里面会进行上面2所说的处理。这个也希望在自定义控件里面解决。


由于上面的仅仅是现在的构思,且这个项目马上就要结束了(MR4.0?Mr8移行),最近比较忙,还没进行实施。
但是已经确定下个项目还是这样的移行。所以希望提前有理论基础。

请问:
上面的动作有没有可能实现?

有没有封装InputMan的单元格的Demo,能不能提供下?

Alice 发表于 2015-12-21 17:25:00

回复 1楼sxyweiren的帖子

谢谢您的反馈。
首先和您需要说的是,您可以将MultiRow8.0和El4.0看成不同的产品,构架和接口都是不同的。

您提到的问题,我们会提到到产品组,确认后给您反馈。

robert 发表于 2015-12-22 10:48:00

不好意思,我只接触过MultiRow8,没有接触过MutliRow4,并不清楚MultiRow4的一些功能和用法。
MultiRow8是全新设计的产品,和MR4只是类似的产品概念并没功能和接口级别的兼容性。如果用户要求很高兼容性的话,不建议直接从MR4升级到MR8.

对于你的问题我会尽力帮你解决。由于我不了解MR4的功能,所有你的问题我没有完全看懂。
1. KeyPreview 事件是什么事件,我并没有找到。是否是PreviewKeyDown事件?
2. 原有的IvalidateRange以及IvalidateValue事件的功能是什么?
3. 动态重构 是什么意思?

对于4,5问题的回答
4. MultiRow8推荐的方法是给Cell起一个名字(设置Name属性),之后通过名字访问Cell
5. MultiRow8的推荐方法是通过处理DataError事件来处理此类问题。无法通过自定义Cell来实现

robert 发表于 2015-12-22 10:50:00

》 有没有封装InputMan的单元格的Demo,能不能提供下?
不知道你的MultiRow是哪个版本, 日文版,中文版还是英文版?

sxyweiren 发表于 2015-12-23 14:01:00

》 有没有封装InputMan的单元格的Demo,能不能提供下?
不知道你的MultiRow是哪个版本, 日文版,中文版还是英文版?
robert 发表于 2015-12-22 10:50:00 http://gcdn.gcpowertools.com.cn/images/common/back.gif


日文版的。

sxyweiren 发表于 2015-12-23 14:21:00

1. KeyPreview 事件是什么事件,我并没有找到。是否是PreviewKeyDown事件?

KeyPreview 就是你说的PreviewKeyDown事件。

2. 原有的IvalidateRange以及IvalidateValue事件的功能是什么?

原有的IvalidateRange以及IvalidateValue跟InputMan4.0的Date控件一样的动作。
IvalidateRange:如果输入的日期不再控件的最大最小值范围内,则返回前回值(最后一次输入正确的值)
IvalidateValue:如果输入非日期类型的值,则返回前回正确的值。

动态重构 是什么意思?
想法是对GcMultiRow进行二次封装,如果Template值被设定时,并且设定的模板是复数行表示的时候,通过循环单元格的形式把模板重新生成下。
举个最简单的例子,如果每条数据是两行显示,第一行是三列,第二行是两列,并且第二行的第一列的宽度和第一行的第一列和第二列的列宽之和相同。
Mr4.0里面会通过代码MR(0,2,1)来定位第二行的第二列。
到了我们封装的Mr8里面,动态的把模板生成为每个小行都是三列的,不过第二行的第二列整成隐藏的,这样
Mr4.0里面的代码MR(0,2,1)可以通过工具替换为MR(0,2+1×3)
※如果动态生成模板实现的话,对于MR(0,2,1)也会定义个方法来通过封装实现,从而减少了处理里面的代码替换。
※因为上班时间没法上传文件,所以可能有点抽象,不好意思。。


其实最重要的问题是MR4.0的LeaveEdit事件,触发的时机比较早,会在CellValidating事件等一系列的事件之前,但是Mr8.0的CellEndEdit事件触发的时机有点晚了。所有的事件之后。
其他事件的触发时机差异也比较大。
事件的问题预计需要通过自定义事件,在需要的时候进行呼出。

※因为属于控件版本升级,所以客户报价稍低,如果还是通过单纯的代码重写来实现,公司会一直处于赤字状态。所以控件的二次封装也就势在必行了。

robert 发表于 2015-12-23 16:30:00

1. 由于单元格处于编辑状态的时候,按下回车键以及左右键甚至F1-F12不会触发MultiRow的KeyPreview事件,因此想要通过自定义单元格呼出GcMultiRow的这些事件。
抱歉,编辑状态是,无法触发MultiRow的PerviewKeyDown事件
2. 由于GcDate以及GcNumber类型的控件,原有的IvalidateRange以及IvalidateValue事件已经没有了。并且值的还原动作也不一样了。所以想要在封装的单元格里面增加这些动作。
CellType 上的MaxMinBehavior属性可能是你想要的
3. Template的动态重构....
个人建议,你可以建立一个数字索引和名字的对应关系来解决这个问题
例如,你设计Template的时候给你认为在第一小行第一列的Cell起名为“0,0” 给第二小行第三小列的Cell起名为“1,2”以此类推
然后你就可以封装如下代码:

    public class MyGcMultiRow : GcMultiRow
    {
      public Cell this
      {
            get
            {
                var cellName = GetCellName(subRow, subColumn);
                return this;
            }
      }

      private string GetCellName(int subRow, int subColumn)
      {
            return subRow + "," + subColumn;
      }
    }


有没有封装InputMan的单元格的Demo,能不能提供下?
自定义InputMan单元格的方法和自定义普通的单元格方法类似。

    public class MyGcTextBoxCellType : GcTextBoxCell
    {
      public override Type EditType
      {
            get
            {
                return typeof(MyGcTextBoxEditingControl);
            }
      }
    }

    public class MyGcTextBoxEditingControl : GcTextBoxEditingControl
    {
    }

需要重写一些函数来达成一些自定义效果。

sxyweiren 发表于 2015-12-24 09:33:00

回复 7楼robert的帖子

1, 由于单元格处于编辑状态的时候,按下回车键以及左右键甚至F1-F12不会触发MultiRow的KeyPreview事件,因此想要通过自定义单元格呼出GcMultiRow的这些事件。
抱歉,编辑状态是,无法触发MultiRow的PerviewKeyDown事件
现在倒是可以在ShortcutKeyManager里面通过自定义Action来实现调用。但是自定义单元格如何实现调用现在还没有方向。

2,CellType 上的MaxMinBehavior属性可能是你想要的
MaxMinBehavior这个属性的动作跟IvalidateRange以及IvalidateValue的动作差距还是挺大的(因为不知道MR4.0做了什么,所以暂定认为是IvalidateRange以及IvalidateValue处理)

根据现有的MaxMinBehavior的可以设定的值分析,Restore这个属性可以返回前回值。
但是MaxMinBehavior这个属性如果不设定为Keep,就意味着输入超过最大值或者最小值的数,不管你输入动作是否完成,单元格的值立马变成对应的值。
比如说单元格的最大值是999,如果我输入了998,然后我再按一下键盘上的9键,这个时候值就自动变更了。后续我想修改或者继续输入只能从变更后的值的基础上做操作了。

这样的动作对于有些人来说是令人不适的。表示一旦你输入错误,你就没有反悔的机会只能重新来过。
所以本次开发我们通过EditingControlShowing事件来吧EditingControl外挂Validating事件实现的。
本次提出来就是想问问能否通过自定义单元格的Validating事件实现同样的效果。


3,有没有封装InputMan的单元格的Demo,能不能提供下?
自定义InputMan单元格的方法和自定义普通的单元格方法类似。
:nbtz5: 你们那边没有现成的例子么?给个参考下呗。。
基本的封装都会,但是对于在自定义控件里面如何实现与GcMultiRow的事件互动不是很了解。
比如自定义单元格要进入编辑状态,能否自定义EditingControl
EditingControl的KeyDown事件里面如何调用MultiRow的Keydown事件。
在比如:上面的问题2,我想通过在MultiRow里面自定义个事件IvalidateRange,如果EditingControl的Validating里面发现值在最大最小范围之外的时候,呼出Mr的IvalidateRange事件。

robert 发表于 2015-12-24 15:17:00

》 我想通过在MultiRow里面自定义个事件IvalidateRange,如果EditingControl的Validating里面发现值在最大最小范围之外的时候,呼出Mr的IvalidateRange事件
    public class MyGcTextBoxCellType : GcTextBoxCell
    {
      public override Type EditType
      {
            get
            {
                return typeof(MyGcTextBoxEditingControl);
            }
      }
    }

    public class MyGcTextBoxEditingControl : GcTextBoxEditingControl
    {
      protected override void OnValidating(CancelEventArgs e)
      {
            base.OnValidating(e);
            
            if(NotInRange(this.Value))
            {
                   (this.GcMultiRow as MyGcMultiRow).OnIvalidateRange(e);
            }
      }
    }

    public class MyGcMultiRow : GcMultiRow
    {
      public event EventHandler<CancelEventArgs> IvalidateRange;

      internal virtual void OnIvalidateRange(CancelEventArgs e)
      {
            if (this.IvalidateRange != null)
            {
                this.IvalidateRange(this, e);
            }
      }

    }

robert 发表于 2015-12-24 15:19:00

&gt; 你们那边没有现成的例子么?给个参考下呗。。
这个确实没有,其实包装InputMan的CellEditor和普通的Cell思路是一样的。只能根据特定的需求来写定制逻辑
页: [1] 2
查看完整版本: 关于MultiRow的自定义单元格的问题