1.主要操作

属性框基本上长这个样子
image.png
与GridControl一样,想要设置行需要添加相应的FiledName和一些控件,比如线路颜色我需要用ColorEdit这个控件
则在In-place Editor中间添加
image.png
image.png

DevExpress容器控件中想要添加的控件一般都是Repository里的
image.png

2.初始设置属性框控件

初始设置PropertyGridControl

  1. /// <summary>
  2. /// 初始设置PropertyGridControl
  3. /// </summary>
  4. void InitialSetPropCtrl()
  5. {
  6. checkBtnPropertySort.CheckedChanged += new EventHandler(checkBtnSort);
  7. checkBtnAZSort.CheckedChanged += new EventHandler(checkBtnSort);
  8. SetBarButtonToolTip(checkBtnPropertySort, "分组排序");
  9. SetBarButtonToolTip(checkBtnAZSort, "按字母排序");
  10. checkBtnPropertySort.Checked = true;
  11. propertyGridControl1.ExpandAllRows();
  12. propertyGridControl1.OptionsBehavior.PropertySort = DevExpress.XtraVerticalGrid.PropertySort.NoSort;
  13. CustomAttribute ca1 = new CustomAttribute();//初始的自定义属性
  14. propertyGridControl1.SelectedObject = ca1;
  15. //
  16. DevExpress.XtraVerticalGrid.Rows.BaseRow br = propertyGridControl1.GetRowByCaption("线路");
  17. //通过循环遍历设置属性的中文名称
  18. foreach (DevExpress.XtraVerticalGrid.Rows.EditorRow per in br.ChildRows)
  19. {
  20. if (per.ChildRows.Count > 0)
  21. { //利用递归解决多层可扩展属性的caption的赋值
  22. SetCustomAttributeCaption(per);
  23. }
  24. string dicKey = per.Properties.FieldName;
  25. if (CustomAttribute.dic.ContainsKey(dicKey))
  26. per.Properties.Caption = CustomAttribute.dic[dicKey];
  27. per.Height = 23;//设置属性行高度
  28. }
  29. }

3.同时自定义了一个CustomAttribute类

  1. /// <summary>
  2. /// 自定义属性类
  3. /// </summary>
  4. public class CustomAttribute
  5. {
  6. /// <summary>
  7. /// 用于存放属性英文-中文的键值对
  8. /// </summary>
  9. public static Dictionary<string, string> dic = new Dictionary<string, string>();
  10. ///初始值,其实可以直接在属性里写默认值
  11. private GMap.NET.WindowsForms.Markers.GMarkerGoogleType _LineStyle= GMap.NET.WindowsForms.Markers.GMarkerGoogleType.none;
  12. private string _LineName = "Unknown";
  13. private int _PointCount = 0;
  14. private bool _IsVisible = false;
  15. private Color _LineColor = Color.Blue;
  16. private bool _IsEditable = false;
  17. public CustomAttribute()
  18. {
  19. dic.Add("LineStyle", "线路标注样式");
  20. dic.Add("PointCount", "线路点个数");
  21. dic.Add("LineName", "线路名称");
  22. dic.Add("IsVisible", "是否隐藏");
  23. dic.Add("LineColor", "线路颜色");
  24. dic.Add("IsEditable", "是否可移动");
  25. }
  26. public CustomAttribute(string LineName,int PointCount,bool IsVisible,GMap.NET.WindowsForms.Markers.GMarkerGoogleType type,Color lineColor,bool isEditable)
  27. {
  28. this.LineName = LineName;
  29. this.PointCount = PointCount;
  30. this.IsVisible = IsVisible;
  31. this.LineStyle = type;
  32. this.LineColor = lineColor;
  33. this.IsEditable = isEditable;
  34. }
  35. //public CustomAttribute()
  36. /// <summary>
  37. /// 线路标注样式
  38. /// </summary>
  39. [Browsable(true), Category("线路")]
  40. public GMap.NET.WindowsForms.Markers.GMarkerGoogleType LineStyle
  41. {
  42. get {return _LineStyle; }
  43. set {_LineStyle=value; }
  44. }
  45. /// <summary>
  46. /// 线路名称
  47. /// </summary>
  48. [Browsable(true), Category("线路")]
  49. public string LineName
  50. {
  51. get {return _LineName; }
  52. set {_LineName=value; }
  53. }
  54. /// <summary>
  55. /// 是否隐藏
  56. /// </summary>
  57. [Browsable(true), Category("线路")]
  58. public bool IsVisible
  59. {
  60. get { return _IsVisible; }
  61. set
  62. {
  63. _IsVisible = value;
  64. }
  65. }
  66. /// <summary>
  67. /// 线路点个数
  68. /// </summary>
  69. [Browsable(true), Category("线路")]
  70. public int PointCount
  71. {
  72. get {return _PointCount; }
  73. set {_PointCount=value; }
  74. }
  75. [Browsable(true), Category("线路")]
  76. public Color LineColor
  77. {
  78. get { return _LineColor; }
  79. set { _LineColor = value; }
  80. }
  81. [Browsable(true), Category("线路")]
  82. public bool IsEditable
  83. {
  84. get { return _IsEditable; }
  85. set { _IsEditable = value; }
  86. }
  87. ///// <summary>
  88. ///// 可展开属性
  89. ///// </summary>
  90. ///// TypeConverter(typeof(ExpandableObjectConverter)):将CustomAttribute1类型的对象转为可扩展对象
  91. //[Browsable(true), Category("自定义属性"), TypeConverter(typeof(ExpandableObjectConverter))]
  92. //public CustomAttribute1 CA1
  93. //{
  94. // get { return _ca1; }
  95. // set
  96. // {
  97. // _ca1 = value;
  98. // }
  99. //}
  100. }
  101. ///// <summary>
  102. ///// 自定义属性类1
  103. ///// </summary>
  104. //class CustomAttribute1
  105. //{
  106. // public CustomAttribute1()
  107. // {
  108. // CustomAttribute.dic.Add("CustomDisplayFormart", "显示类型");
  109. // CustomAttribute.dic.Add("CustomFormartString", "类型格式");
  110. // }
  111. // private CustomAttribute2 _CustomDisplayFormart;
  112. // private string _CustomFormartString = "";
  113. // /// <summary>
  114. // /// 显示类型
  115. // /// </summary>
  116. // [Browsable(true), TypeConverter(typeof(ExpandableObjectConverter))]
  117. // public CustomAttribute2 CustomDisplayFormart
  118. // {
  119. // get { return _CustomDisplayFormart; }
  120. // set
  121. // {
  122. // _CustomDisplayFormart = value;
  123. // }
  124. // }
  125. // /// <summary>
  126. // /// 类型格式
  127. // /// </summary>
  128. // public string CustomFormartString
  129. // {
  130. // get { return _CustomFormartString; }
  131. // set
  132. // {
  133. // _CustomFormartString = value;
  134. // }
  135. // }
  136. //}
  137. ///// <summary>
  138. ///// 自定义属性类2
  139. ///// </summary>
  140. //class CustomAttribute2
  141. //{
  142. // public CustomAttribute2()
  143. // {
  144. // CustomAttribute.dic.Add("CustomDisplayFormartValue", "显示格式值");
  145. // CustomAttribute.dic.Add("AllowUseCustomDisplayFormart", "是否启用显示格式");
  146. // }
  147. // private string _CustomDisplayFormartValue = "";
  148. // private CustomAttribute.VisibleStatus _AllowUseCustomDisplayFormart = CustomAttribute.VisibleStatus.False;
  149. // /// <summary>
  150. // /// 值
  151. // /// </summary>
  152. // public string CustomDisplayFormartValue
  153. // {
  154. // get { return _CustomDisplayFormartValue; }
  155. // set
  156. // {
  157. // _CustomDisplayFormartValue = value;
  158. // }
  159. // }
  160. // /// <summary>
  161. // /// 是否启用
  162. // /// </summary>
  163. // public CustomAttribute.VisibleStatus AllowUseCustomDisplayFormart
  164. // {
  165. // get { return _AllowUseCustomDisplayFormart; }
  166. // set
  167. // {
  168. // _AllowUseCustomDisplayFormart = value;
  169. // }
  170. // }
  171. //}

4.一些方法

把自定义属性CustomAttribute中的Dictionary键值加入到EditorRow里,Caption和Value
这里是添加初始属性框的描述、添加自定义属性、设置当前属性

  1. /// <summary>
  2. /// 设置自定义属性的描述
  3. /// </summary>
  4. private void SetCustomAttributeCaption(DevExpress.XtraVerticalGrid.Rows.EditorRow EditorRow)
  5. {
  6. foreach (DevExpress.XtraVerticalGrid.Rows.EditorRow per_child in EditorRow.ChildRows)
  7. {
  8. if (per_child.ChildRows.Count > 0)
  9. {
  10. //利用递归解决多层可扩展属性的caption的赋值
  11. SetCustomAttributeCaption(per_child);
  12. }
  13. //FieldName属性包含了该属性的父属性FieldName;通过 . 分割
  14. string[] per_child_FieldName = per_child.Properties.FieldName.Split('.');
  15. string dicKey = per_child_FieldName[per_child_FieldName.GetLength(0) - 1];
  16. if (CustomAttribute.dic.ContainsKey(dicKey))
  17. per_child.Properties.Caption = CustomAttribute.dic[dicKey];
  18. per_child.Height = 23;//设置属性行高度
  19. }
  20. }
  21. /// <summary>
  22. /// 添加到全局变量的CustomAttributes
  23. /// </summary>
  24. /// <param name="overlay">图层</param>
  25. /// <param name="IsSetPropCtrl">是否添加到属性框里</param>
  26. /// <param name="isVisible">是否隐藏这一栏</param>
  27. private void AddCustomAttribute(GMapOverlay overlay, bool IsSetPropCtrl, bool isVisible, System.Drawing.Color color, bool isEditable)
  28. {
  29. CustomAttribute attribute = new CustomAttribute(overlay.Id, overlay.Markers.Count, isVisible, ((GMarkerGoogle)overlay.Markers[0]).Type, color, isEditable);
  30. customAttributes.Add(attribute);
  31. if (!isEditable)//不可编辑即锁定状态
  32. { chooseLocked.Add(overlay.Id); }
  33. currentAttribute = attribute;
  34. if (IsSetPropCtrl)
  35. {
  36. SetCurrentCustomAttribute(overlay.Id);
  37. }
  38. }
  39. /// <summary>
  40. /// 设置当前的自定义属性
  41. /// </summary>
  42. /// <param name="overlayname">当前图层的名称</param>
  43. private void SetCurrentCustomAttribute(string overlayname)
  44. {
  45. var currentCustom = customAttributes.Find(a => a.LineName == overlayname);
  46. this.propertyGridControl1.SelectedObject = currentCustom;
  47. currentAttribute = currentCustom;
  48. //
  49. DevExpress.XtraVerticalGrid.Rows.BaseRow br = propertyGridControl1.GetRowByCaption("线路");
  50. //通过循环遍历设置属性的中文名称
  51. //foreach (DevExpress.XtraVerticalGrid.Rows.PGridEditorRow per in br.ChildRows)
  52. foreach (DevExpress.XtraVerticalGrid.Rows.EditorRow per in br.ChildRows)
  53. {
  54. if (per.ChildRows.Count > 0)
  55. { //利用递归解决多层可扩展属性的caption的赋值
  56. SetCustomAttributeCaption(per);
  57. }
  58. string dicKey = per.Properties.FieldName;
  59. if (CustomAttribute.dic.ContainsKey(dicKey))
  60. per.Properties.Caption = CustomAttribute.dic[dicKey];
  61. per.Height = 23;//设置属性行高度
  62. }
  63. }

image.png

5.事件

 #region 属性框事件
        //CheckButton.CheckeChange事件
        void checkBtnSort(object sender, EventArgs e)
        {
            CheckButton thisChk = (CheckButton)sender;
            if (thisChk == checkBtnPropertySort)
            {
                if (checkBtnPropertySort.Checked)
                    SetBarButtonDown(checkBtnAZSort, false);
                else
                    SetBarButtonDown(checkBtnAZSort, true);
            }
            else
            {
                if (checkBtnAZSort.Checked)
                    SetBarButtonDown(checkBtnPropertySort, false);
                else
                    SetBarButtonDown(checkBtnPropertySort, true);
            }
            UpdatePropertyGrid();
        }
        //设置按钮的鼠标悬浮气泡提示信息
        static void SetBarButtonToolTip(CheckButton chkBtn, string value)
        {
            DevExpress.Utils.SuperToolTip superToolTip = new DevExpress.Utils.SuperToolTip();
            DevExpress.Utils.ToolTipTitleItem toolTipTitleItem = new DevExpress.Utils.ToolTipTitleItem();
            toolTipTitleItem.Text = value;
            superToolTip.Items.Add(toolTipTitleItem);
            chkBtn.SuperTip = superToolTip;
        }
        //设置按钮是否按下
        void SetBarButtonDown(CheckButton chkBtn, bool value)
        {
            chkBtn.CheckedChanged -= new EventHandler(checkBtnSort);
            chkBtn.Checked = value;
            chkBtn.CheckedChanged += new EventHandler(checkBtnSort);
        }
        //更改控件排序方式
        void UpdatePropertyGrid()
        {
            this.propertyGridControl1.OptionsView.ShowRootCategories = this.checkBtnPropertySort.Checked;
        }

        //属性框cell的值改变
        private void propertyGridControl1_CellValueChanged(object sender, DevExpress.XtraVerticalGrid.Events.CellValueChangedEventArgs e)
        {
            try
            {
                var rowFieldName = e.Row.Name.ToString();
                switch (rowFieldName)
                {
                    case "LineStyle":
                        ChangeLineStyle((GMarkerGoogleType)e.Value);
                        break;
                    case "IsVisible":
                        currentAttribute.IsVisible = (bool)e.Value;
                        break;
                    case "LineColor":
                        ChangeLineMarkerColor((System.Drawing.Color)e.Value);
                        break;
                    default:
                        break;
                }
            }
            catch (Exception ex)
            {
                WriteLog(ex.Message);
                XtraMessageBox.Show(ex.Message);
            }
        }

        #endregion
        #endregion

        #region 更改线路标注或者颜色(xml文件和其他文件分开处理)

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        private void ChangeLineStyle(GMarkerGoogleType type)
        {
            var overlay = gMapOverlays.Find(a => a.Id == currentAttribute.LineName);
            currentOverlay = overlay;
            //改变customAttribute的属性
            var customattribute = customAttributes.Find(a => a.LineName == currentAttribute.LineName);
            customattribute.LineStyle = type;
            if (overlay.Id.Contains(".xml"))//
            {
                List<GMarkerGoogleExt> points = new List<GMarkerGoogleExt>();
                foreach (GMapMarker marker in overlay.Markers)
                {
                    GMarkerGoogleExt newmarker = UpdateMarker(marker, type);
                    points.Add(newmarker);
                }
                overlay.Markers.Clear();
                foreach (GMarkerGoogleExt a in points)
                {
                    overlay.Markers.Add(a);
                }
                this.gmap.Refresh();
            }
            else
            {
                GMarkerGoogleExt pfirst = UpdateMarker(overlay.Markers[0], type);
                GMarkerGoogleExt plast = UpdateMarker(overlay.Markers.Last(), type);
                overlay.Markers.RemoveAt(0);
                overlay.Markers.Insert(0, pfirst);
                overlay.Markers.RemoveAt(overlay.Markers.IndexOf(overlay.Markers.Last()));
                overlay.Markers.Add(plast);
                this.gmap.Refresh();
            }
        }

        /// <summary>
        /// 改变线路文件的起始点和终点的Marker样式
        /// </summary>
        /// <param name="c">颜色</param>
        private void ChangeLineMarkerColor(System.Drawing.Color c)
        {
            var overlay = gMapOverlays.Find(a => a.Id == currentAttribute.LineName);
            var customattribute = customAttributes.Find(a => a.LineName == currentAttribute.LineName);
            customattribute.LineColor = c;
            if (!(overlay.Id.Contains(".xml")))//不是xml文件
            {
                for (int i = 1; i < overlay.Markers.Count - 1; i++)
                {
                    GMarkerGoogleExt newmarker = UpdateMarker(overlay.Markers[i], c);
                    overlay.Markers.RemoveAt(i);
                    overlay.Markers.Insert(i, newmarker);
                }
                foreach (GMapRouteExt route in overlay.Routes)
                {
                    route.Stroke = new Pen(c, 3);
                }
                this.gmap.Refresh();
            }
            else
            {
                foreach (GMapRouteExt route in overlay.Routes)
                {
                    route.Stroke = new Pen(c, 3);
                }
                this.gmap.Refresh();
            }
        }

        /// <summary>
        /// 更新Marker的标注类型
        /// </summary>
        /// <param name="marker"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        private GMarkerGoogleExt UpdateMarker(GMapMarker marker, GMarkerGoogleType type)
        {
            GMarkerGoogleExt newmarker = new GMarkerGoogleExt(marker.Position, type);
            newmarker.ToolTipText = marker.ToolTipText;
            newmarker.ToolTip.Foreground = Brushes.Black;
            newmarker.ToolTip.TextPadding = new Size(20, 10);
            return newmarker;
        }

        /// <summary>
        /// 更新Marker的颜色
        /// </summary>
        /// <param name="marker"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        private GMarkerGoogleExt UpdateMarker(GMapMarker marker, System.Drawing.Color c)
        {
            GMarkerGoogleExt newmarker = new GMarkerGoogleExt(marker.Position, ((GMarkerGoogle)marker).Type, c, 5, true);
            newmarker.ToolTipText = marker.ToolTipText;
            newmarker.ToolTip.Foreground = Brushes.Black;
            newmarker.ToolTip.TextPadding = new Size(20, 10);
            return newmarker;
        }

        /// <summary>
        /// 更新Marker的位置和ToolTipText
        /// </summary>
        /// <returns></returns>
        private GMarkerGoogleExt UpdateMarker(GMarkerGoogleExt marker, int index, PointLatLng point)
        {
            GMarkerGoogleExt newmarker = marker;
            newmarker.Position = point;
            newmarker.ToolTipText = string.Format("点编号{0}:经度{1},纬度{2}", index, point.Lng, point.Lat);
            newmarker.ToolTip.Foreground = Brushes.Black;
            newmarker.ToolTip.TextPadding = new Size(20, 10);
            return marker;
        }
        #endregion