C# 如何使用PropertyGrid允许在没有设置器的情况下编辑属性?
默认情况下,PropertyGrid仅允许使用公共setter编辑属性。我想允许在没有setter的情况下编辑属性 例如:C# 如何使用PropertyGrid允许在没有设置器的情况下编辑属性?,c#,.net,winforms,propertygrid,C#,.net,Winforms,Propertygrid,默认情况下,PropertyGrid仅允许使用公共setter编辑属性。我想允许在没有setter的情况下编辑属性 例如: class A { public int X {get;set} public int Y {get;} } 在上面的示例中,只有X是可编辑的。Y将显示,但灰显。如何使Y可编辑 注意:创建一个私有支持字段就可以了。例如: class A { public int X {get;set} private int y; public in
class A {
public int X {get;set}
public int Y {get;}
}
在上面的示例中,只有X是可编辑的。Y将显示,但灰显。如何使Y可编辑
注意:创建一个私有支持字段就可以了。例如:
class A {
public int X {get;set}
private int y;
public int Y {get => y; }
}
有一种方法可以做到这一点,但它非常复杂
创建自定义TypeDescriptionProvider并将其链接到类型,或在类型中实现ICustomTypeDescriptor,以及
创建一个自定义PropertyDescriptor,它知道如何编辑GetValue和SetValue中的字段
您创建了一个定制的TypeDescriptor,它与大多数事物的标准属性描述符相呼应,在本例中是您的新属性描述符
但是,非常严肃地说;请不要这样做!首先,只需让酒店可访问即可。如果它不是可设置的属性,则不应尝试设置它
根据评论,听起来你真正需要的是冰棒的不变性;考虑:
福班{
私人银行冻结;
公共作废冻结=>\u冻结=true;
受保护的空位{
如果已冻结,则抛出新的InvalidOperationException
调用冻结后,无法更改对象;
}
私人机构;
公共整数X{
get=>\ux;
设置{
如果值!=\u x{
ThrowIfFrozen;
_x=值;
}
}
}
公共智力{
get=>\u y;
设置{
如果值!=\u y{
ThrowIfFrozen;
_y=值;
}
}
}
}
有一种方法可以做到这一点,但它非常复杂
创建自定义TypeDescriptionProvider并将其链接到类型,或在类型中实现ICustomTypeDescriptor,以及
创建一个自定义PropertyDescriptor,它知道如何编辑GetValue和SetValue中的字段
您创建了一个定制的TypeDescriptor,它与大多数事物的标准属性描述符相呼应,在本例中是您的新属性描述符
但是,非常严肃地说;请不要这样做!首先,只需让酒店可访问即可。如果它不是可设置的属性,则不应尝试设置它
根据评论,听起来你真正需要的是冰棒的不变性;考虑:
福班{
私人银行冻结;
公共作废冻结=>\u冻结=true;
受保护的空位{
如果已冻结,则抛出新的InvalidOperationException
调用冻结后,无法更改对象;
}
私人机构;
公共整数X{
get=>\ux;
设置{
如果值!=\u x{
ThrowIfFrozen;
_x=值;
}
}
}
公共智力{
get=>\u y;
设置{
如果值!=\u y{
ThrowIfFrozen;
_y=值;
}
}
}
}
您可以基于构建包装器/代理类,该类允许您在运行时调整属性 这是您可以使用它的方式:
var a = new A();
// build a proxy
var proxy = new Proxy(a);
// tweak any properties
proxy.Properties["Y"].IsReadOnly = false;
// you can also tweak attributes
proxy.Properties["Y"].Attributes.Add(new CategoryAttribute("R/O -> R/W"));
proxy.Properties["Y"].Attributes.Add(new DescriptionAttribute("This works"));
// handle property change
propertyGrid1.PropertyValueChanged += (s, e) =>
{
if (e.ChangedItem.PropertyDescriptor.Name == "Y")
{
a.Y = (int)e.ChangedItem.Value;
}
};
// select the proxy instead of the original instance
propertyGrid1.SelectedObject = proxy;
结果如下
您可以基于构建包装器/代理类,该类允许您在运行时调整属性 这是您可以使用它的方式:
var a = new A();
// build a proxy
var proxy = new Proxy(a);
// tweak any properties
proxy.Properties["Y"].IsReadOnly = false;
// you can also tweak attributes
proxy.Properties["Y"].Attributes.Add(new CategoryAttribute("R/O -> R/W"));
proxy.Properties["Y"].Attributes.Add(new DescriptionAttribute("This works"));
// handle property change
propertyGrid1.PropertyValueChanged += (s, e) =>
{
if (e.ChangedItem.PropertyDescriptor.Name == "Y")
{
a.Y = (int)e.ChangedItem.Value;
}
};
// select the proxy instead of the original instance
propertyGrid1.SelectedObject = proxy;
结果如下
X甚至会显示在属性网格中吗?我认为它没有列出字段,即使是公共的。。。至少:不是默认的提供程序;当然,你可以覆盖它course@MarcGravell对不起,你是对的,可能不是。我徒劳地做了这件事,以证明我希望实现的目标,并犯了一个错误。我更正了它。你们可以给它一个setter,但若在运行时调用它,它会抛出一个异常。X甚至会显示在属性网格中吗?我认为它没有列出字段,即使是公共的。。。至少:不是默认的提供程序;当然,你可以覆盖它course@MarcGravell对不起,你是对的,可能不是。我徒劳地做了这件事,以证明我希望实现的目标,并犯了一个错误。我更正了它。您可以给它一个setter,但如果在运行时调用它,可以将其编程为抛出异常。