如何为自定义控件添加值为某个结构的属性?

SadEmprie 2010-11-17 02:55:25
控件TT继承自TextBox,TT中有个public属性MyPro,类型的MyStruct

定义为
public struct MyStruct
{
public byte i;
public byte j;

public MyStruct(byte a, byte b)
{
i = a;
j = b;
}
}


可是为什么控件的属性窗口中,属性MyPro是灰色的?不能像控件的Padding或Size属性那样展开一个属性菜单,然后设置里面的值?
...全文
191 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
边城的刀声 2010-11-17
  • 打赏
  • 举报
回复
那如果你想控制它在“源”视图中的数据怎么办,也就是序列化的时候,可以通过PersistenceMode来设置,具体 的值楼主可以看下MSDN里的详细介绍

[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public MyStruct MyPro

结果

<MyPro I="1" J="2" />

这样易读多了
边城的刀声 2010-11-17
  • 打赏
  • 举报
回复
如果想展开分别设置i和j呢?,继承下ExpandableObjectConverter,并公布出i和j

[DefaultProperty("Text")]
[ToolboxData("<{0}:HasCustomClassProperty runat=server></{0}:HasCustomClassProperty>")]
public class HasCustomClassProperty : WebControl
{
[TypeConverter(typeof(MyStructConverter))]
[Browsable(true)]
public MyStruct MyPro
{
get { return ViewState["MyPro"] == null ? default(MyStruct) : (MyStruct) ViewState["MyPro"]; }
set { ViewState["MyPro"] = value; }
}



protected override void RenderContents(HtmlTextWriter output)
{
output.Write(String.Format("i:{0}",MyPro.I));
output.Write(String.Format("j:{0}", MyPro.J));
}
}

public class MyStructConverter : ExpandableObjectConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(String))
{
return true;
}

return base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is String)
{
String[] values = value.ToString().Split(',');
MyStruct result = new MyStruct(Byte.Parse(values[0]), Byte.Parse(values[1]));
return result;
}
else
{
return base.ConvertFrom(context, culture, value);
}
}

public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(String))
{
MyStruct myStruct = (MyStruct) value;
return String.Format("{0},{1}", myStruct.I, myStruct.J);
}
else
{
return base.ConvertTo(context, culture, value, destinationType);
}
}

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(String))
{
return true;
}
else
{
return base.CanConvertTo(context, destinationType);
}
}
}

[Serializable]
public struct MyStruct
{
private byte i;
private byte j;

public MyStruct(byte a, byte b)
{
i = a;
j = b;
}

public byte J
{
get { return j; }
set { j = value; }
}

public byte I
{
get { return i; }
set { i = value; }
}
}

边城的刀声 2010-11-17
  • 打赏
  • 举报
回复
得指定自定义的TypeConverter,我写了个例子

[DefaultProperty("Text")]
[ToolboxData("<{0}:HasCustomClassProperty runat=server></{0}:HasCustomClassProperty>")]
public class HasCustomClassProperty : WebControl
{
[TypeConverter(typeof(MyStructConverter))]
[Browsable(true)]
public MyStruct MyPro
{
get { return ViewState["MyPro"] == null ? default(MyStruct) : (MyStruct) ViewState["MyPro"]; }
set { ViewState["MyPro"] = value; }
}



protected override void RenderContents(HtmlTextWriter output)
{
output.Write(String.Format("i:{0}",MyPro.i));
output.Write(String.Format("j:{0}", MyPro.j));
}
}

public class MyStructConverter : TypeConverter
{
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
if (sourceType == typeof(String))
{
return true;
}

return base.CanConvertFrom(context, sourceType);
}

public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
{
if (value is String)
{
String[] values = value.ToString().Split(',');
MyStruct result = new MyStruct(Byte.Parse(values[0]), Byte.Parse(values[1]));
return result;
}
else
{
return base.ConvertFrom(context, culture, value);
}
}

public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(String))
{
MyStruct myStruct = (MyStruct) value;
return String.Format("{0},{1}", myStruct.i, myStruct.j);
}
else
{
return base.ConvertTo(context, culture, value, destinationType);
}
}

public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
{
if (destinationType == typeof(String))
{
return true;
}
else
{
return base.CanConvertTo(context, destinationType);
}
}
}

[Serializable]
public struct MyStruct
{
public byte i;
public byte j;

public MyStruct(byte a, byte b)
{
i = a;
j = b;
}
}
yangqizhong 2010-11-17
  • 打赏
  • 举报
回复
我觉得用类,然后把get set 都写出来,一起实现吧
边城的刀声 2010-11-17
  • 打赏
  • 举报
回复
如果能编辑才叫有问题呢
兔子-顾问 2010-11-17
  • 打赏
  • 举报
回复
我想当然了。看这个文章介绍的吧。
http://hi.baidu.com/wanhongnan/blog/item/e0d9863de9901603baa1670a.html/cmtid/122369cfd1137331f9dc6164
whrspsoft3723 2010-11-17
  • 打赏
  • 举报
回复
看来问题已经解决了
itrefer 2010-11-17
  • 打赏
  • 举报
回复
属性上加标签[Browsable(true), Category("XX"), Description("XX")]

如果想自动选择 试试 枚举 (没试过)
DataBox-MDX 2010-11-17
  • 打赏
  • 举报
回复
因为你这里只定义了访问属性,没定义设置属性:
public byte i;
public byte j;
改为:

private byte _i;
Public byte i
{
get {return _i;}
set { _i=value;}
}
private byte _j;
Public byte j
{
get {return _j;}
set { _j=value;}
}
兔子-顾问 2010-11-17
  • 打赏
  • 举报
回复
因为吧struct作为属性的时候,get返回的是属性的副本,所以设计器对值类型属性设置为只读,因为你实际修改了副本的字段并不能对控件本身那个属性有改变。
你用类就可以了。

111,129

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧