找回密码
 立即注册

QQ登录

只需一步,快速开始

bingdaoice

中级会员

44

主题

208

帖子

608

积分

中级会员

积分
608
bingdaoice
中级会员   /  发表于:2020-7-17 15:23  /   查看:11617  /  回复:20
1金币
本帖最后由 bingdaoice 于 2020-7-17 16:00 编辑

问题1:当Spread有多个Sheets时,必须每个Sheets都指定一下Changed 事件吗?能不能直接Spread指定Changed 事件(他的每一个Sheets改变内容时都触发)?
for (int i = 0; i < Spread_RecdCertif.Sheets.Count; i++)
{
    Spread_RecdCertif.Sheets.Models.Data.Changed += Data_RecdChanged;                     
}

问题2:Data_RecdChanged触发时,能不能获由是哪个Sheets触发的,然后好准确的设置该单元格的SetNote。      
image.png104655455.png

问题3:如何在Data_RecdChanged触发时,指定某单元格的NoteStyleInfo。(就是上图错误的地方,如何解决?)

问题4:使用SetValue会触发Changed事件,但是当有公式的单元格引用了此单元格,公式单元格的值改变时没有触发Changed事件。
如何让有公式的单元格值改变时也触发Changed事件(这个很重要,要求有改变时必须记录原值是什么)?

问题5:在Spread上手动修改值时也没有触发Changed事件,如何在手动修改值时触发Changed事件?



20 个回复

倒序浏览
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2020-7-17 17:33:32
沙发
spread控件本身就有Change事件,可以直接使用

  1.         private void fpSpread1_Change(object sender, FarPoint.Win.Spread.ChangeEventArgs e)
  2.         {
  3.             int sheetindex = e.View.ActiveSheetIndex;
  4.             int row = e.Row;
  5.             int col = e.Column;
  6.         }
复制代码
回复 使用道具 举报
bingdaoice
中级会员   /  发表于:2020-7-20 09:23:22
板凳
你好,版主。Change事件只能是用户手动修改数据时会触发。(使用SetValue和公式单元格自动计算都不会触发)
我想要的事件是。单元格值要改变时(但值还未改变)时就触发
用SetValue、手动修改、公式单元格自动计算时改变,都触发的事件。
想触发这个事件的原因是:当单元格值改变后,记录单元格改变前的值是什么?
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2020-7-20 12:10:32
地板
目前,控件没有提供Changing事件,因此没有办法获取改变前的值

另外,Change事件对应的是界面中单元格值的改变,只是手动修改数据是会触发
你用的fpSpread1.Sheets[0].Models.Data.Changed,这个对应的是数据,
回复 使用道具 举报
bingdaoice
中级会员   /  发表于:2020-7-20 15:34:28
5#
本帖最后由 bingdaoice 于 2020-7-20 15:40 编辑

是的,以前我做这个项目的DEMO的时候就咨询过的。是可以获取到的值。
但是现在SetValue是可以触发Changed。
但是公式单元格自动计算不会触发Changed。不知道是怎么回事了,以前用12的版本是可以的,验证过的(因为此功能是必须功能,所以在很早前就验证过,关于公式的获取修改前的值也有是一套办法的),但现在公式不触发。我这边项目都可能通不过了。

现在的问题就是:
1、Changed事件时,能不能获由是哪个Sheets触发的,然后好准确的设置该单元格的SetNote。并且设置NoteStyleInfo。
2、公式单元格自动计算不会触发Changed。


请版主帮帮我。
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2020-7-20 18:11:29
6#
你好,
1关于公式单元格自动计算不会触发Changed,这个我会验证后给你答复,看看是否是版本差异

2.判断由哪个Sheet触发的Changed事件,可以用每个Sheet分别绑定一个Changed事件来判断fpSpread1.Sheets[0].Models.Data.Changed

3.你说的关于公式修改前的值的获取,我不确定是你是怎样获取的,请详细说明一下

因为您这一块的问题较多且涉及其他的老版本,我建议你可以给我私信一个联系方式,我电话和你沟通一下具体情况,看看如何解决
回复 使用道具 举报
bingdaoice
中级会员   /  发表于:2020-7-21 08:35:01
7#
本帖最后由 bingdaoice 于 2020-7-21 10:20 编辑

1、好的,谢谢版主。以前确实是可以的。(今天我恢复了一个12.2的版本,测试了一下。公式单元格的值改变时是可以触发Changed事件的,版主可以测试一下。下图是我用的12.2的版本及信息)
2、由于我的fpSpread中的Sheets数量并不固定,所以分别使用的话,可能会有点麻烦。
目前的情况是,我会检测Sheets中的工作表,看哪几个工作表启用了,就把启用的几个连接Changed事件,所以才想在Changed触发的时候想要获取是具体由哪个Sheets触发的,我才好准确的设置对应单元格的SetNote。
3、公式单元格修改前的值的获取方式是,我在Form_Load的时候把启用的Sheets表里面都遍历一遍,获取哪张表哪个单元格有公式。然后存在DataTable里面,当单元格公式值改变时触发Changed事件时,我判断该单元格是否有公式,如果有,再从DataTable里面取出先前得到的值,并设置公式单元格的SetNote。
我的联系方式是:15882201102

image.png189914855.png
回复 使用道具 举报
Richard.Ma讲师达人认证 悬赏达人认证 SpreadJS 开发认证
超级版主   /  发表于:2020-7-21 12:02:44
8#
刚才和你电话沟通的情况来看,12版本可能也只能解决一部分公式单元格问题,你可以把你这边获取公式单元格修改前的值的代码发上来,我是使用现有版本和老版本对比测试看看
回复 使用道具 举报
bingdaoice
中级会员   /  发表于:2020-7-21 12:36:20
9#
本帖最后由 bingdaoice 于 2020-7-21 12:48 编辑

        public void ViewRecdCertif(DataTable tblDict)//打开XML
        {
            try
            {         
                Spread_RecdCertif.Open(p_certif.GetRecdTempFile(p_certif.DetailId, true, 2));
                Spread_RecdCertif.Tag = "R" + p_certif.DetailId.ToString();
                GetUserStringValue(Spread_RecdCertif, ref tblFormula, true);//遍历Spread所有Sheets,将有公式的单元格的SheetsIndex,ROW,COL,Value存入DataTable中,待公式值改变时获取使用。
                    for (int i = 0; i < Spread_RecdCertif.Sheets.Count; i++)
                    {
                        Spread_RecdCertif.Sheets.Models.Data.Changed += Data_Changed;                              
                    }
            }
            catch (Exception exc)
            {
                MessageBox.Show(exc.Message);
            }
        }

        /// <summary>
        /// 获取所有单元格的自定义字符串值(书签)
        /// 获取有公式的单元格SheetsIndex,Row,Col

        /// </summary>
        public void GetUserStringValue(FpSpread Spread, ref DataTable dt, bool GetFormula)
        {
            dt.Clear(); bool AddTable = false;
            for (int s = 0; s < Spread.Sheets.Count; s++)
            {
                for (int i = 0; i < Spread.Sheets.RowCount; i++)
                {
                    for (int j = 0; j < Spread.Sheets.ColumnCount; j++)
                    {
                        AddTable = false;
                        if (GetFormula == true && Spread.Sheets.GetFormula(i, j) != "")
                            AddTable = true;
                        else if (Spread.Sheets.GetTag(i, j) != null)
                            AddTable = true;
                        if (AddTable == true)
                        {
                            string UserValue = "";
                            try
                            {
                                UserValue = Spread.Sheets.GetTag(i, j).ToString();
                            }
                            catch
                            {

                            }
                            if (!cmbUserValue.Items.Contains(UserValue) && UserValue != "标准器" && UserValue != "原始记录标题")
                            {
                                DataRow NewRow = dt.NewRow();
                                NewRow["Idx"] = s;
                                NewRow["Row"] = i;
                                NewRow["Col"] = j;
                                NewRow["UserValue"] = UserValue;
                                NewRow["ShowValue"] = Spread.Sheets.GetText(i, j).ToString();
                                NewRow["CellValue"] = Spread.Sheets.GetText(i, j).ToString();
                                NewRow["State"] = 0;
                                NewRow["ValueType"] = 0;
                                if (UserValue.Contains("图片"))
                                    NewRow["ValueType"] = 1;
                                if (Spread.Sheets.GetFormula(i, j) != "")
                                    NewRow["ValueType"] = 2;
                                NewRow["Protect"] = 0;
                                if (cmbUserValue.Items.Contains(UserValue) || UserValue.Contains("图片"))
                                    NewRow["Protect"] = 1;
                                dt.Rows.Add(NewRow);
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// 当用户手动修改单元格的值改变前触发
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Spread_RecdCertif_EditChange(object sender, FarPoint.Win.Spread.EditorNotifyEventArgs e)
        {
            OldValue = Spread_RecdCertif.ActiveSheet.GetText(e.Row, e.Column).ToString();
        }
        /// <summary>
        /// 当用户手动粘贴内容时触发
        /// </summary>
        private void Spread_RecdCertif_ClipboardPasting(object sender, ClipboardPastingEventArgs e)
        {
            OldValue = Spread_RecdCertif.ActiveSheet.GetText(startRow, startCol).ToString();
        }

        /// <summary>
        /// 当单元格内容改变后触发,13的版本公式单元格自动计算改变时和引用的单元格改变时都不会触发,
       /// 12.2版本引用的单元格值改变时会触发,但公式单元格如SUM(A1:A10)不会触发
        /// </summary>
        private void Data_Changed(object sender, SheetDataModelEventArgs e)
        {             var sv = (DefaultSheetDataModel)sender;
             if (UpModen == true)
                {               
                    if (sv.GetFormula(e.Row, e.Column) != "")//此段公式获取有错误,无法获取到由哪个Sheets触发,及不能判断正确位置。
                    {
                        tblFormula.DefaultView.RowFilter = "Row=" + e.Row + " and Col=" + e.Column;
                        if (tblFormula.DefaultView.Count > 0)
                        {
                            OldValue = tblFormula.DefaultView[0].Row["CellValue"].ToString();
                            tblFormula.DefaultView[0].Row["ShowValue"] = Spread_RecdCertif.ActiveSheet.GetText(e.Row, e.Column).ToString();
                            tblFormula.DefaultView[0].Row["CellValue"] = Spread_RecdCertif.ActiveSheet.GetText(e.Row, e.Column).ToString();
                        }
                    }
        else   if (SetNoteState == false) //此处设置 SetNote 有错误,没有明确设置哪个Sheets中的Row 和Column的Note,以及无法设置SetStickyNoteStyleInfo
                        {
                            SetNoteState = true;
                            RichTextBox Rtx = new RichTextBox();
                            string OldTip = Spread_RecdCertif.ActiveSheet.GetNote(e.Row, e.Column);
                            Rtx.Text = OldTip + "[" + AppEnvironment.Operator.OpeName + "][" + DateTime.Now.ToString() + "][" + OldValue + "]\r\n";
                            Spread_RecdCertif.ActiveSheet.SetNote(e.Row, e.Column, Rtx.Text);

                            //Spread_RecdCertif.Sheets[0].notes.NoteStyle = FarPoint.Win.Spread.NoteStyle.PopupStickyNote;
                            //sv.Cells[e.Row, e.Column].NoteIndicatorSize = new Size(8, 8);
                            //FarPoint.Win.Spread.DrawingSpace.StickyNoteStyleInfo si = new FarPoint.Win.Spread.DrawingSpace.StickyNoteStyleInfo();
                            //si.Width = 300;
                            //si.Height = 15 * Rtx.Lines.Length;
                            //sv.SetStickyNoteStyleInfo(e.Row, e.Column, si);
                            //SetNoteState = false;
                           SetNoteState = false;
                     }
                }
        }



回复 使用道具 举报
bingdaoice
中级会员   /  发表于:2020-7-21 12:44:53
10#
个人建议:1、当单元格内容发生改变前:不管是用户手动、使用SetValue、粘贴内容,公式自动计算等;凡是内容改变了,都触发EditChange事件,这样就能获取到内容发生改变前的值。一个接口就全部获取了。
2、当内容改变后都触发Change,也可以获取到修后改的值了。




回复 使用道具 举报
123下一页
您需要登录后才可以回帖 登录 | 立即注册
返回顶部