Esempio n. 1
0
        public void DeleteVariable(VarDefine var, bool confirm,
                                   HashSet <BeanDefine> deletedBeanDefines, HashSet <EnumDefine> deletedEnumDefines)
        {
            if (var.Parent.Locked)
            {
                MessageBox.Show("bean is Locked");
                return;
            }

            if (confirm)
            {
                if (DialogResult.OK != MessageBox.Show("确定删除?所有引用该列的数据也会被删除。", "确认", MessageBoxButtons.OKCancel))
                {
                    return;
                }
            }

            // delete data and column, all reference.
            foreach (var doc in CollectDocumentNeedUpdate(var))
            {
                doc.GridData?.DeleteVariable(var);
            }
            ;
            // delete define
            var.Delete(deletedBeanDefines, deletedEnumDefines);
        }
Esempio n. 2
0
        public void AddReferenceFrom(VarDefine var, ReferenceFrom.Reasons reason)
        {
            var fullName = var.Parent.FullName();

            _ReferenceFroms.Add($"{fullName}:{var.Name}", new ReferenceFrom(fullName, var.Name, reason));
            Document.IsChanged = true;
        }
Esempio n. 3
0
        /// <summary>
        /// 在当前搜索使用参数变量的的所有列的值,并且构建EnumDefine。
        /// 不合法的Enum名字忽略。
        /// 仅在 FromDefine 里面调用。
        /// </summary>
        /// <param name="var"></param>
        public void BuildEnumFor(VarDefine var)
        {
            if (FormMain.Instance.Tabs.SelectedTab == null)
            {
                return;
            }

            var          enumDefine = new EnumDefine(var.Parent, var.Name);
            DataGridView grid       = (DataGridView)FormMain.Instance.Tabs.SelectedTab.Controls[0];

            for (int i = 0; i < grid.ColumnCount; ++i)
            {
                if ((grid.Columns[i].Tag as ColumnTag).PathLast.Define == var)
                {
                    for (int j = 0; j < grid.RowCount - 1; ++j)
                    {
                        var valueName = grid[i, j].Value as string;
                        if (null == Tools.VerifyName(valueName, CheckNameType.CheckOnly))
                        {
                            // 增加enum定义。
                            enumDefine.ChangeValueName(new EnumDefine.ValueDefine(enumDefine, "", -1), valueName);
                        }
                    }
                }
            }
            var.Parent.AddEnumDefine(enumDefine);
            InsertEnumDefine(define.RowCount, enumDefine.FullName(), enumDefine);
        }
Esempio n. 4
0
 public void RemoveVariable(VarDefine var)
 {
     if (_Variables.Remove(var))
     {
         Document.IsChanged = true;
     }
 }
Esempio n. 5
0
 private void UpdateWhenAddVariable(int rowIndex, VarDefine var, bool create)
 {
     if (null != var)
     {
         InsertVariable(rowIndex, var);
         if (create && IsLoadedDocument(var.Reference.Document))
         {
             string fullName    = var.Reference.FullName();
             int    insertIndex = 0;
             for (; insertIndex < define.RowCount; ++insertIndex)
             {
                 DataGridViewCellCollection cells = define.Rows[insertIndex].Cells;
                 if (cells["BeanLocked"].Tag == null)
                 {
                     continue;
                 }
                 if (fullName.CompareTo(cells["VarName"].Value as string) < 0)
                 {
                     break;
                 }
             }
             InsertBeanDefine(insertIndex, fullName, var.Reference);
         }
     }
 }
Esempio n. 6
0
 public ColumnTag AddVar(VarDefine define, int index)
 {
     Path.Add(new VarInfo()
     {
         Define = define, ListIndex = index
     });
     return(this);
 }
Esempio n. 7
0
 public void UpdateWhenAddVariable(VarDefine var)
 {
     foreach (var doc in CollectDocumentNeedUpdate(var))
     {
         doc.GridData?.UpdateWhenAddVariable(var);
     }
     ;
 }
Esempio n. 8
0
        private HashSet <Document> CollectDocumentNeedUpdate(VarDefine var)
        {
            HashSet <Document> docs = new HashSet <Document>();

            // 自己所在的文档实际上不一定需要更新,有可能仅被其他文档引用。
            // 由于 root bean 不会记录自己的引用,所以没办法,总是加入。
            // 这个不会造成问题,因为后面的操作仅更新实际搜索到引用的地方。
            docs.Add(var.Parent.Document);
            foreach (var reff in var.Parent.ReferenceFroms.Values)
            {
                var refBeanDefine = Documents.SearchReference(reff.FullName);
                docs.Add(refBeanDefine.Document);
            }
            return(docs);
        }
Esempio n. 9
0
        public void DeleteVariable(VarDefine var)
        {
            View?.SuspendLayout();
            var updateParam = new Bean.UpdateParam()
            {
                UpdateType = Bean.EUpdate.DeleteData
            };                                                                                 // never change

            for (int c = 0; c < ColumnCount; ++c)
            {
                ColumnTag tagref = Columns[c].ColumnTag;
                if (tagref.PathLast.Define == var)
                {
                    // delete data
                    for (int r = 0; r < RowCount; ++r)
                    {
                        var row    = Rows[r];
                        int colref = c;
                        Document.Beans[r].Update(this, row, ref colref, 0, updateParam);
                    }
                    // delete columns
                    switch (tagref.Tag)
                    {
                    case ColumnTag.ETag.Normal:
                        this.RemoveColumn(c);
                        --c;
                        break;

                    case ColumnTag.ETag.ListStart:
                        int colListEnd = GridData.FindCloseListEnd(this, c);
                        while (colListEnd >= c)
                        {
                            RemoveColumn(colListEnd);
                            --colListEnd;
                        }
                        --c;
                        break;

                    default:
                        MessageBox.Show("ListEnd?");
                        break;
                    }
                }
            }
            View?.ResumeLayout();
        }
Esempio n. 10
0
        private void InsertVariable(int rowIndex, VarDefine var)
        {
            define.Rows.Insert(rowIndex, 1);
            DataGridViewCellCollection cellsVar = define.Rows[rowIndex].Cells;

            cellsVar["BeanLocked"].ReadOnly = true;
            DataGridViewCell cellVar = cellsVar["VarName"];

            cellVar.Value                   = var.Name;
            cellVar.Tag                     = var;
            cellsVar["VarType"].Value       = var.Type;
            cellsVar["VarValue"].Value      = var.Value;
            cellsVar["VarForeign"].Value    = var.Foreign;
            cellsVar["VarProperties"].Value = var.Properties;
            cellsVar["VarDefault"].Value    = var.Default;
            cellsVar["VarComment"].Value    = var.Comment;
        }
Esempio n. 11
0
 public void ReloadAllGridIfContains(VarDefine var)
 {
     foreach (var tab in tabs.Controls)
     {
         DataGridView gridref = (DataGridView)((TabPage)tab).Controls[0];
         //if (gridref.Tag == )
         for (int i = 0; i < gridref.ColumnCount; ++i)
         {
             ColumnTag tagref = gridref.Columns[i].Tag as ColumnTag;
             if (tagref.PathLast.Define == var)
             {
                 ReloadGridsAfterFormDefineClosed.Add(gridref);
                 break;
             }
         }
     }
 }
Esempio n. 12
0
        public void Move(VarDefine src, VarDefine before)
        {
            int srcIndex = _Variables.IndexOf(src);

            if (srcIndex < 0)
            {
                return;
            }
            int beforeIndex = _Variables.IndexOf(before);

            if (beforeIndex < 0)
            {
                return;
            }
            _Variables.RemoveAt(srcIndex);
            _Variables.Insert(beforeIndex, src);
            if (null != src.Self && null != before.Self)
            {
                XmlNode parent   = src.Self.ParentNode;
                bool    srcFirst = true;
                foreach (var childNode in parent.ChildNodes)
                {
                    if (childNode == src.Self)
                    {
                        srcFirst = true;
                        break;
                    }
                    if (childNode == before.Self)
                    {
                        srcFirst = false;
                        break;
                    }
                }
                parent.RemoveChild(src.Self);
                if (srcFirst)
                {
                    parent.InsertAfter(src.Self, before.Self);
                }
                else
                {
                    parent.InsertBefore(src.Self, before.Self);
                }
            }
            Document.IsChanged = true;
        }
Esempio n. 13
0
        public string OpenForeign(string foreign, out VarDefine foreignVar)
        {
            foreignVar = null;
            if (string.IsNullOrEmpty(foreign))
            {
                return(null);
            }

            string[] newForeign = foreign.Split(':');
            if (newForeign.Length != 2)
            {
                return("错误的Foreign格式。sample 'ConfigName:VarName'");
            }

            var beanRef = FormMain.Instance.Documents.SearchReference(newForeign[0]);

            if (null == beanRef)
            {
                return("foreign Bean 不存在。");
            }

            foreignVar = beanRef.GetVariable(newForeign[1]);
            if (null == foreignVar)
            {
                return("foreign Bean 变量不存在。");
            }

            if (foreignVar.Parent.Parent != null)
            {
                return("只能 foreign 到文档的 Root Bean。");
            }

            if (foreignVar.Type == EType.List)
            {
                return("foreign VarType 不能为 List。");
            }

            if (foreignVar.Type != Type)
            {
                return("foreign Bean 变量类型和当前数据列的类型不匹配。");
            }

            return(null);
        }
Esempio n. 14
0
        private void EditProperties(int rowIndex, int colIndex)
        {
            if (rowIndex < 0)
            {
                return;
            }

            DataGridViewCellCollection cells = define.Rows[rowIndex].Cells;
            VarDefine var = cells["VarName"].Tag as VarDefine;

            if (null == var || null == var.Name)
            {
                return;
            }

            if (!define.Columns[colIndex].Name.Equals("VarProperties"))
            {
                return;
            }

            DataGridViewCell cell = cells["VarProperties"];
            FormProperties   fp   = new FormProperties()
            {
                Properties = var.PropertiesList,
                FormDefine = this,
            };

            if (DialogResult.OK == fp.ShowDialog(this))
            {
                List <Property.IProperty> current = new List <Property.IProperty>();
                foreach (var p in FormMain.Instance.PropertyManager.Properties)
                {
                    if (p.Value.ButtonChecked)
                    {
                        current.Add(p.Value);
                    }
                    p.Value.Button = null;
                }
                var.Properties = FormMain.Instance.PropertyManager.BuildString(current);
                cell.Value     = var.Properties;
            }
            fp.Dispose();
        }
Esempio n. 15
0
        private void DeleteVariable(int rowIndex, VarDefine var, bool confirm)
        {
            var deletedBeanDefines = new HashSet <BeanDefine>();
            var deletedEnumDefines = new HashSet <EnumDefine>();

            FormMain.Instance.DeleteVariable(var, confirm, deletedBeanDefines, deletedEnumDefines);

            define.SuspendLayout();
            define.Rows.RemoveAt(rowIndex);
            foreach (var beanDefine in deletedBeanDefines)
            {
                if (!IsLoadedDocument(beanDefine.Document))
                {
                    continue;
                }

                // remove bean
                DeleteRowsByBeanLockedTag(beanDefine);

                /*
                 * beanDefine.ForEach((BeanDefine bd) =>
                 * {
                 *  foreach (var enumdef in bd.EnumDefines.Values)
                 *  {
                 *      // remove enum
                 *      DeleteRowsByBeanLockedTag(enumdef);
                 *  }
                 *  return true;
                 * });
                 */
            }
            foreach (var enumDefine in deletedEnumDefines)
            {
                if (!IsLoadedDocument(enumDefine.Parent.Document))
                {
                    continue;
                }
                DeleteRowsByBeanLockedTag(enumDefine);
            }
            define.ResumeLayout();
        }
Esempio n. 16
0
        public void UpdateWhenAddVariable(VarDefine var)
        {
            for (int c = 0; c < ColumnCount; ++c)
            {
                ColumnTag tagref = Columns[c].ColumnTag;
                if (tagref.Tag == ColumnTag.ETag.AddVariable && tagref.PathLast.Define.Parent == var.Parent)
                {
                    c += var.BuildGridColumns(this, c, tagref.Parent(ColumnTag.ETag.Normal), -1);

                    // 如果是List,第一次加入的时候,默认创建一个Item列。
                    // 但是仍然有问题:如果这个Item没有输入数据,下一次打开时,不会默认创建。需要手动增加Item。
                    if (var.Type == VarDefine.EType.List)
                    {
                        ColumnTag tagListEnd     = Columns[c - 1].ColumnTag;
                        ColumnTag tagListEndCopy = tagListEnd.Copy(ColumnTag.ETag.Normal);
                        tagListEndCopy.PathLast.ListIndex = -tagListEnd.PathLast.ListIndex; // 肯定是0,保险写法。
                        --tagListEnd.PathLast.ListIndex;
                        c += var.Reference.BuildGridColumns(this, c - 1, tagListEndCopy, -1);
                    }
                    //((Document)gridref.Tag).IsChanged = true; // 引用的Grid仅更新界面,数据实际上没有改变。
                }
            }
        }
Esempio n. 17
0
        // 如果由于不再被引用,需要删除类定义时,返回this,否则返回null。
        public void RemoveReferenceFrom(VarDefine var,
                                        HashSet <BeanDefine> deletedBeanDefines, HashSet <EnumDefine> deletedEnumDefines,
                                        bool willAddBack = false)
        {
            var fullName         = var.Parent.FullName();
            var referenceFromKey = $"{fullName}:{var.Name}";

            if (_ReferenceFroms.TryGetValue(referenceFromKey, out var exist))
            {
                if (null != exist.Self)
                {
                    exist.Self.ParentNode.RemoveChild(exist.Self);
                }
                exist.Self = null;
                _ReferenceFroms.Remove(referenceFromKey);
                // 本来想Foreign弄成弱引用,由于Foreign只能引用root,肯定不会被删除。强弱就无所谓了。
                if (false == willAddBack)
                {
                    TryDeleteThis(deletedBeanDefines, deletedEnumDefines);
                }
                Document.IsChanged = true;
            }
        }
Esempio n. 18
0
 // return null if check ok // foreign.Reference 已经初始化了,这里要不要使用?
 public string OpenForeign(out VarDefine foreignVar)
 {
     return(OpenForeign(Foreign, out foreignVar));
 }
Esempio n. 19
0
        public ColumnTag(ETag tag, VarDefine define, int index)
        {
            this.Tag = tag;

            AddVar(define, index);
        }
Esempio n. 20
0
        public (VarDefine, bool) AddVariable(VarDefine hint)
        {
            if (hint.Parent.Locked)
            {
                MessageBox.Show("bean is Locked");
                return(null, false);
            }

            FormInputVarDefine input = new FormInputVarDefine();

            input.StartPosition = FormStartPosition.CenterParent;

            // 初始化 input.ComboBoxBeanDefines。
            // 如果要全部定义,调用 LoadAllDocument.
            List <string> beanDefineFullNames = new List <string>();

            Documents.ForEachFile((Documents.File file) =>
            {
                file.Document?.BeanDefine.CollectFullNameIncludeSubBeanDefine(beanDefineFullNames);
                return(true);
            });
            beanDefineFullNames.Sort();
            input.ComboBoxBeanDefines.Items.AddRange(beanDefineFullNames.ToArray());

            string    varName      = "";
            VarDefine result       = null;
            bool      createResult = false;

            while (true)
            {
                input.TextBoxVarName.Text = varName;
                if (DialogResult.OK != input.ShowDialog(this))
                {
                    break;
                }

                try
                {
                    varName = input.TextBoxVarName.Text;
                    if (null != Tools.VerifyName(varName, CheckNameType.ShowMsg))
                    {
                        continue;
                    }
                    VarDefine.EType varType = VarDefine.ToEType(input.ComboBoxVarType.Text);
                    (VarDefine var, bool create, string err) =
                        hint.Parent.AddVariable(varName, varType, input.ComboBoxBeanDefines.Text);

                    if (null == var)
                    {
                        MessageBox.Show(err);
                        continue;
                    }
                    result       = var;
                    createResult = create;
                    this.UpdateWhenAddVariable(var);
                    break;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.ToString());
                }
            }
            input.Dispose();
            return(result, createResult);
        }
Esempio n. 21
0
        /// <summary>
        /// AddVariable
        /// </summary>
        /// <param name="name"></param>
        /// <param name="type"></param>
        /// <param name="reference"></param>
        /// <returns>error string.</returns>
        public (VarDefine, bool, string) AddVariable(string name,
                                                     VarDefine.EType type = VarDefine.EType.Undecided, string reference = null)
        {
            if (GetVariable(name) != null)
            {
                return(null, false, "duplicate variable name");
            }

            VarDefine var = new VarDefine(this, name)
            {
                Type  = type,
                Value = reference,
                GridColumnValueWidth = 50,
            };

            bool create = false;

            switch (type)
            {
            case VarDefine.EType.List:
                if (string.IsNullOrEmpty(reference))
                {
                    var.Value = var.FullName();
                    if (_BeanDefines.TryGetValue(var.Name, out var exist))
                    {
                        if (false == exist.NamespaceOnly)
                        {
                            return(null, false, $"尝试为变量'{var.Name}'创建一个 BeanDefine 失败:已经存在。");
                        }
                    }
                    else
                    {
                        exist = new BeanDefine(Document, var.Name, this);
                        _BeanDefines.Add(var.Name, exist);
                    }
                    var.Reference = exist;
                    exist.AddReferenceFrom(var, ReferenceFrom.Reasons.List);
                    create = true;
                }
                else
                {
                    var r = FormMain.Instance.Documents.SearchReference(var.Value);
                    if (null == r)
                    {
                        return(null, false, "list reference bean not found.");
                    }
                    var.Reference = r;
                    r.AddReferenceFrom(var, ReferenceFrom.Reasons.List);
                }
                break;

            case VarDefine.EType.Enum:
                _EnumDefines.Add(var.Name, new EnumDefine(this, var.Name));
                break;
            }

            _Variables.Add(var);
            var.CreateXmlElementIfNeed(); // 调整变量顺序的时候需要这个创建好。
            Document.IsChanged = true;
            return(var, create, "");
        }
Esempio n. 22
0
        private void Build()
        {
            try
            {
                FormMain.Instance.SaveAll();
                FormMain.Instance.Documents.LoadAllDocument(this);

                if (FormMain.Instance.FormError.GetErrorCount() > 0)
                {
                    FormMain.Instance.InvokeShowFormError();
                    this.AppendLine("当前打开的文档存在一些验证错误。停止Build。", Color.Red);
                    return;
                }

                // verify
                FormMain.Instance.Documents.ForEachFile((Documents.File file) =>
                {
                    var doc = file.Document;
                    if (doc.GridData != null)
                    {
                        return(Running); // 已经打开的文档,有即时验证。
                    }
                    this.AppendLine($"Verify {doc.RelateName}", Color.Black);
                    int ErrorCount = 0;
                    FormMain.Instance.FormError.OnAddError = (GridData.Cell cell, Property.IProperty p, Property.ErrorLevel level, string desc) =>
                    {
                        if (cell.Row.GridData == doc.GridData)
                        {
                            ++ErrorCount;
                        }
                    };
                    doc.BuildGridData();
                    doc.GridData.VerifyAll(false);
                    if (ErrorCount > 0)
                    {
                        FormMain.Instance.InvokeOpenGrid(doc, false);
                    }
                    else
                    {
                        // 等 FormError 处理了有 GridData 但是没有 View 的情况,可以不清除错误。
                        // FormMain.Instance.FormError.RemoveErrorByGrid(doc.GridData);
                    }
                    return(Running);
                });
                FormMain.Instance.FormError.OnAddError = null;

                if (false == Running)
                {
                    return;
                }

                // 输出服务器使用的配置数据。现在是xml格式。
                string serverDir = System.IO.Path.Combine(FormMain.Instance.ConfigProject.DataOutputDirectory, "Server");
                FormMain.Instance.Documents.ForEachFile((Documents.File file) =>
                {
                    this.AppendLine($"导出服务器配置. {file.Document.RelateName}", Color.Black);
                    string serverDocDir = System.IO.Path.Combine(serverDir, file.Parent.RelateName);
                    System.IO.Directory.CreateDirectory(serverDocDir);
                    string serverFileName = System.IO.Path.Combine(serverDocDir, file.Document.Name + ".xml");
                    file.Document.SaveAs(serverFileName, true, Property.DataOutputFlags.Server);
                    return(Running);
                });

                if (false == Running)
                {
                    return;
                }
                // check VarDefine.Default
                VarDefine hasDefaultError = null;
                FormMain.Instance.Documents.ForEachFile((Documents.File file) =>
                {
                    return(file.Document.BeanDefine.ForEach((BeanDefine beanDefine) =>
                    {
                        foreach (var varDefine in beanDefine.Variables)
                        {
                            if (false == varDefine.CheckType(varDefine.TypeNow, varDefine.Default))
                            {
                                hasDefaultError = varDefine;
                                return false;
                            }
                        }
                        return Running;
                    }));
                });
                if (hasDefaultError != null)
                {
                    this.AppendLine(hasDefaultError.FullName() + " 默认值和类型不匹配。", Color.Red);
                    return;
                }
                if (false == Running)
                {
                    return;
                }

                Gen.cs.Main.Gen(FormMain.Instance, Property.DataOutputFlags.Server, this);

                if (false == Running)
                {
                    return;
                }

                switch (string.IsNullOrEmpty(FormMain.Instance.ConfigProject.ClientLanguage)
                    ? "cs" : FormMain.Instance.ConfigProject.ClientLanguage)
                {
                case "cs":
                    Gen.cs.Main.Gen(FormMain.Instance, Property.DataOutputFlags.Client, this);
                    // 输出客户端使用的配置数据。xml格式。
                    string clientDir = System.IO.Path.Combine(FormMain.Instance.ConfigProject.DataOutputDirectory, "Client");
                    FormMain.Instance.Documents.ForEachFile((Documents.File file) =>
                    {
                        this.AppendLine($"导出cs客户端数据. {file.Document.RelateName}", Color.Black);
                        string clientDocDir = System.IO.Path.Combine(clientDir, file.Parent.RelateName);
                        System.IO.Directory.CreateDirectory(clientDocDir);
                        string clientFileName = System.IO.Path.Combine(clientDocDir, file.Document.Name + ".xml");
                        file.Document.SaveAs(clientFileName, true, Property.DataOutputFlags.Client);
                        return(Running);
                    });

                    break;

                case "ts":
                    // 生成代码,数据也嵌入在代码中。
                    Gen.ts.Main.Gen(FormMain.Instance, Property.DataOutputFlags.Client, this);
                    break;

                case "lua":
                    // 生成代码,数据也嵌入在代码中。
                    Gen.lua.Main.Gen(FormMain.Instance, Property.DataOutputFlags.Client, this);
                    break;

                default:
                    this.AppendLine("unkown client language: " + FormMain.Instance.ConfigProject.ClientLanguage, Color.Red);
                    break;
                }
            }
            catch (Exception ex)
            {
                this.AppendLine(ex.ToString(), Color.Red);
            }
            finally
            {
                WaitBuildExit.Set();
            }
        }
Esempio n. 23
0
        private void define_CellValidating(object sender, DataGridViewCellValidatingEventArgs e)
        {
            if (e.ColumnIndex < 0)
            {
                return;
            }

            if (e.RowIndex < 0)
            {
                return;
            }

            if (false == define.IsCurrentCellInEditMode)
            {
                return;
            }

            DataGridViewCellCollection cells = define.Rows[e.RowIndex].Cells;

            if (cells["BeanLocked"].Tag != null)
            {
                // assert(cells["VarName"] == cells[e.ColumnIndex]);
                var newValue = e.FormattedValue as string;
                if (null != Tools.VerifyName(newValue, CheckNameType.ShowMsg))
                {
                    e.Cancel = true;
                    return; // VerifyName 里面已经显示消息了。
                }
                return;
            }

            DataGridViewCell cellVarName = cells["VarName"];

            if (null == cellVarName.Tag)
            {
                e.Cancel = true;
                MessageBox.Show("只有VarName.Tag设置的行才允许编辑,其他的应该都设置了 ReadOnly. 怎么到这里的?");
                return;
            }

            if (cellVarName.Tag is EnumDefine.ValueDefine valueDefine)
            {
                string colName = define.Columns[e.ColumnIndex].Name;
                switch (colName)
                {
                case "VarName":
                    var newValue = e.FormattedValue as string;
                    if (null != Tools.VerifyName(newValue, CheckNameType.ShowMsg))
                    {
                        e.Cancel = true;
                        return;
                    }
                    if (false == valueDefine.Name.Equals(newValue) &&
                        null != valueDefine.Parent.GetValueDefine(newValue))
                    {
                        e.Cancel = true;
                        MessageBox.Show("enum.value 重名了。");
                        return;
                    }
                    break;

                case "VarValue":
                    if (false == int.TryParse(e.FormattedValue as string, out var _))
                    {
                        e.Cancel = true;
                        MessageBox.Show("enum.value只能是整数。");
                        return;
                    }
                    break;
                }
                return;
            }

            // modify Var
            VarDefine var = cellVarName.Tag as VarDefine;

            if (null == var.Name) // var.Name is null when row is ',' for addvar
            {
                e.Cancel = true;  // 肯定时readonly吧。怎么到这里的。
                return;
            }

            try
            {
                string colName = define.Columns[e.ColumnIndex].Name;
                switch (colName)
                {
                case "VarName":
                    string newVarName = e.FormattedValue as string;
                    if (var.Name.Equals(newVarName))
                    {
                        return;
                    }

                    if (null != Tools.VerifyName(newVarName, CheckNameType.ShowMsg))
                    {
                        e.Cancel = true;
                        return;     // VerifyName 里面已经显示消息了。
                    }
                    if (var.Parent.GetVariable(newVarName) != null)
                    {
                        e.Cancel = true;
                        MessageBox.Show("变量名字重复了。");
                        return;
                    }
                    break;

                case "VarValue":
                    string newValue = e.FormattedValue as string;
                    if (false == string.IsNullOrEmpty(newValue))
                    {
                        var r = FormMain.Instance.Documents.SearchReference(newValue);
                        e.Cancel = r == null;
                        if (e.Cancel)
                        {
                            MessageBox.Show("引用的Bean名字没有找到。输入空将创建一个。");
                        }
                    }
                    break;

                case "VarForeign":
                    string errForeign = var.OpenForeign(e.FormattedValue as string, out var _);
                    if (null != errForeign)
                    {
                        e.Cancel = true;
                        MessageBox.Show(errForeign);
                    }
                    break;

                case "VarType":
                    VarDefine.EType newType = (VarDefine.EType)System.Enum.Parse(
                        typeof(VarDefine.EType), e.FormattedValue as string);
                    string errType = var.CanChangeTo(newType);
                    if (null != errType)
                    {
                        e.Cancel = true;
                        MessageBox.Show(errType);
                    }
                    break;

                case "VarDefault":
                    if (false == var.CheckType(var.Type, e.FormattedValue as string))
                    {
                        e.Cancel = true;
                        MessageBox.Show("这个默认值和当前类型不匹配。");
                    }
                    break;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
                e.Cancel = true;
            }
        }