Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何使用PropertyGrid允许在没有设置器的情况下编辑属性?_C#_.net_Winforms_Propertygrid - Fatal编程技术网

C# 如何使用PropertyGrid允许在没有设置器的情况下编辑属性?

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

默认情况下,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 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,但如果在运行时调用它,可以将其编程为抛出异常。