/// <summary> /// 初始化子属性行 /// </summary> private void InitSubRow() { if (this.SubRows != null) { this.SubRows.Clear(); } if (this._propertyInfo == null) { return; } //看这个属性对象是否还有需要初始化为子属性行的属性(Property) foreach (PropertyInfo propertyInfoChild in this._propertyInfo.PropertyType.GetProperties()) { PropertyRelatorAttribute propertyGirdAttribute = null; PropertyRelatorAttribute[] attributes = (PropertyRelatorAttribute[])propertyInfoChild.GetCustomAttributes(typeof(PropertyRelatorAttribute), true); if (attributes == null || attributes.Length == 0) { continue; } propertyGirdAttribute = attributes[0]; //至此,确定这是一个要显示的子属性 PropertyGridRow propertyGirdRowChild = new PropertyGridRow(propertyGirdAttribute, propertyInfoChild, this._propertyGrid); if (this.SubRows == null) { this.SubRows = new List <PropertyGridRow>(); } propertyGirdRowChild.ParentRow = this; this.SubRows.Add(propertyGirdRowChild); } }
/// <summary> /// 初始化对象的属性行 /// </summary> /// <param name="attribute"></param> private void InitializePropertyRow(Object obj) { Type type = obj.GetType(); //将类型注册到行集合 #region 判断类型是否已经缓存过属性行,如果有,使用缓存的行,然后return if (_propertyGirdRowCache.IsCached(type)) { //使用缓存时有一个情况必须考虑,那就是行在当前情况下(如选择的对象个数)是否还有效的问题 foreach (PropertyGridRow row in _propertyGirdRowCache.GetPropertyGridRow(type)) { //确保清除当前缓存的行上的对象选择 row.SetSelectedObjects(null); if (row.CanVisible) { PropertyGridRows.Add(row); } } return; } #endregion #region 迭代类型的Properties foreach (PropertyInfo propertyInfo in type.GetProperties()) { PropertyRelatorAttribute propertyGirdAttribute = null; PropertyRelatorAttribute[] attributes = (PropertyRelatorAttribute[])propertyInfo.GetCustomAttributes(typeof(PropertyRelatorAttribute), true); if (attributes == null || attributes.Length == 0) { continue; } propertyGirdAttribute = attributes[0]; //至此,确定需要加载当前的属性行 /* * 原本会用一个if查找 PropertyGirdRowCollection 中是否已经有了同样(同名)的属性信息,如果有就不new新的行了,也不走到cache * 这样有一个问题,如果一上来就多选了多个不同的对象,这些对象会有共有的属性(Property) * 如果判断this.PropertyGridRows中有了就不new 新row,不cache这个新的row,就会造成缓存中被选中的一些类型的对象的属性行不完整 * 因为他们没有机会被初始化,被缓存,因为在走到他们的这些属性(propertyinfo时,其它对象同名的属性行已经被加到 this.PropertyGridRows中了 * 所以这里不能因为 this.PropertyGridRows中有了就不初始化不缓存 * this.PropertyGridRows.Add方法可以照调,方法内部会判断是否已经存在了同名的属性行 */ PropertyGridRow propertyGirdRow = new PropertyGridRow(propertyGirdAttribute, propertyInfo, this); if (this.PropertyGridRows.Contains(propertyGirdRow.PropertyName) == false) { this.PropertyGridRows.Add(propertyGirdRow); } _propertyGirdRowCache.Cache(new PropertyGridRowCacheItem(type, propertyGirdRow)); } #endregion }
/// <summary> /// 构造,应使用此构造,将SelectedObject的初始化留在后面处理,因为要兼容多对象同时选中 /// </summary> /// <param name="attribute"></param> /// <param name="propertyInfoName"></param> public PropertyGridRow(PropertyRelatorAttribute attribute, PropertyInfo propertyInfo, PropertyGridPad propertyGrid) { this._propertyRelatorAttribute = attribute; this._propertyInfo = propertyInfo; this._propertyGrid = propertyGrid; #region 初始化单元格 DataGridViewCell dcPropertyName = new DataGridViewTextBoxCell(); dcPropertyName.Value = attribute.PropertyDisplayName; this.Cells.Add(dcPropertyName); DataGridViewCell dcDescription = new DataGridViewTextBoxCell(); dcDescription.Value = attribute.Description; this.Cells.Add(dcDescription); #region 初始化用于编辑属性值的单元格 //获取PropertyEditorAttribute PropertyEditorAttribute[] editorAttribute = (PropertyEditorAttribute[])propertyInfo.GetCustomAttributes(typeof(PropertyEditorAttribute), true); if (editorAttribute == null || editorAttribute.Length == 0) { //没有加PropertyEditorAttribute的Attribute,分配一个默认的文本框做为编辑控件 //TODO:分配一个默认的文本框做为编辑控件 } else { //创建属性(Property)单元格 _propertyGridCell = CellFactory.Instance.Create(editorAttribute[0]) as DataGridViewCell; //TODO:这里要考虑没有创建出合适的cell的情况,既_propertyGridCell为null的情况 _iPropertyGirdCell = _propertyGridCell as IPropertyGirdCell; _iPropertyGirdCell.PropertyRelatorAttribute = attribute; //查找并设置(如果有)DefaultValueAttribute DefaultValueAttribute[] defaultValueAttribute = (DefaultValueAttribute[])propertyInfo.GetCustomAttributes(typeof(DefaultValueAttribute), true); if (defaultValueAttribute != null && defaultValueAttribute.Length > 0) { _iPropertyGirdCell.DefaultValueAttribute = defaultValueAttribute[0]; } //查找并设置(如果有)PropertyEditorAttribute if (editorAttribute != null && editorAttribute.Length > 0) { _iPropertyGirdCell.PropertyEditorAttribute = editorAttribute[0]; } } _iPropertyGirdCell.Owner = this._propertyGrid; _iPropertyGirdCell.OwnerRow = this; _propertyGridCell.Style.BackColor = Color.White; _propertyGridCell.Style.ForeColor = Color.Black; _propertyGridCell.Style.SelectionBackColor = Color.White; _propertyGridCell.Style.SelectionForeColor = Color.Black; this.Cells.Add(_propertyGridCell); #endregion DataGridViewCell dcProperty = new DataGridViewTextBoxCell(); //属性的真实名 dcProperty.Value = propertyInfo.Name; this.Cells.Add(dcProperty); #endregion //此处的只读设置是享有最高优先级的 this.ReadOnly = attribute.ReadOnly; //初始化子属性行 InitSubRow(); }