使用属性网格时,我怎样才能让它允许我一次为多个对象设置一个属性(当有第二级时)。如果两个属性具有相同的值,一切似乎都可以正常工作,但如果属性不相等,则 propertygrid 不会加载子属性(从箭头向右),因此无法设置它们。我创建了以下示例,对于代码的长度感到抱歉。
public partial class Form1 : Form
{
public Form1()
{
this.Size = new Size(275, 568);
PropertyGrid grid = new PropertyGrid();
grid.Dock = DockStyle.Fill;
this.Controls.Add(grid);
Control c1 = new Control();
c1.Border.Bottom.Color = Color.Red;
Control c2 = new Control();
c2.Border.Bottom.Color = Color.Red;
Control c3 = new Control();
c3.Border.Bottom.Color = Color.Purple;
//This works as expected
//grid.SelectedObject = c1;
//This works as expected
//grid.SelectedObjects = new object[] { c1, c2 };
//This does not work
grid.SelectedObjects = new object[] { c1, c3 };
}
}
class Control
{
public Control()
{
Border = new Border();
Text = "Text";
}
public string Text { get; set; }
[TypeConverter(typeof(BorderConverter))]
public Border Border { get; set; }
}
class Border
{
public Border()
{
Top = new Line();
Bottom = new Line();
Right = new Line();
Left = new Line();
}
[TypeConverter(typeof(LineConverter))]
public Line Top { get; set; }
[TypeConverter(typeof(LineConverter))]
public Line Left { get; set; }
[TypeConverter(typeof(LineConverter))]
public Line Bottom { get; set; }
[TypeConverter(typeof(LineConverter))]
public Line Right { get; set; }
public override bool Equals(object obj)
{
if ((obj as Border) == null)
return false;
Border b = (Border)obj;
return b.Left.Equals(Left) &&
b.Right.Equals(Right) && b.Top.Equals(Top)
&& b.Bottom.Equals(Bottom);
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public class BorderConverter
: TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return attributes == null ? TypeDescriptor.GetProperties(value) : TypeDescriptor.GetProperties(value, attributes);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
}
class Line
{
public Line()
{
Color = Color.Black;
Wieght = 0;
}
public Color Color { get; set; }
public int Wieght { get; set; }
public override bool Equals(object obj)
{
if ((obj as Line) == null)
return false;
Line l = (Line)obj;
return l.Color == Color && l.Wieght == Wieght;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
}
public class LineConverter
: TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return base.CanConvertFrom(context, sourceType);
}
public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
return ((destinationType == typeof(InstanceDescriptor)) || base.CanConvertTo(context, destinationType));
}
public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
{
if (propertyValues == null) throw new ArgumentNullException("propertyValues");
try
{
Line bs = new Line();
bs.Color = (Color)propertyValues["Color"];
bs.Wieght = (int)propertyValues["Wieght"];
return bs;
}
catch (Exception ex) { throw new Exception("Invalid Property value.", ex); }
}
public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return attributes == null ? TypeDescriptor.GetProperties(value) : TypeDescriptor.GetProperties(value, attributes);
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return base.GetStandardValuesSupported(context);
}
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
}