请问我如何写我的类MyClass,可以像.net属性编辑器一样 修改创建的MyClass对象的名字?
//例如,我创建了一个对象
MyClass myc1;
我想通过PropertyGrid 把 myc1变成 myc2
25 个解决方案
#1
class MyClass
{
string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
新增一个public的可读写Name属性即可
{
string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
新增一个public的可读写Name属性即可
#2
控件的Name是用于生成代码时命名的
而你这个是名称已经确定,要进行修改,不一样
#3
一般的控件Control类都有个“(Name)”属性
你的MyClass类里自己添加一个Name属性就可以了,Control类里的Name属性已经封装好了 所以看不到
你的MyClass类里自己添加一个Name属性就可以了,Control类里的Name属性已经封装好了 所以看不到
#4
把myc1变成 myc2 是修改对象的名字
而Name属性,是对象属性的修改,不一样吧
而Name属性,是对象属性的修改,不一样吧
#5
.net 的SDK上说要继承ISite接口,还要设置关联的 IContainer,比较生涩难懂。
谁有例子啊?
谁有例子啊?
#6
I would suggest you don't do it.
Your PropertyGrid works in the runtime but the code serialization (generating code in the Form1.Designer.cs) happens in the design time.
#7
这个名字是对象的名称,就跟变量一样,是编译时使用的,不可以动态更改!~~
2#的name是类的成员,就可以跟其它成员一样赋值了
2#的name是类的成员,就可以跟其它成员一样赋值了
#8
即使Control对象的Name也只是在设计时可以修改。
你可以尝试在PropertyGrid中编辑一个自带的Control,比如TextBox。但是控件的Name属性并不会显示在PropertyGrid中。
你可以尝试在PropertyGrid中编辑一个自带的Control,比如TextBox。但是控件的Name属性并不会显示在PropertyGrid中。
#9
当然是在设计时修改,
我就是自定义了一个控件有个Items属性,在设计时点击Items属性时弹出一个窗体,然后可以编辑这个Items列表,就像ListView控件的Items属性一样
#10
一个类如果是IComponent,那么它就可以放入设计窗口中。(name)并不是真正类的属性,而是设计器通过IExtenderProviderService服务提供的扩展属性。
由于Component实现了IComponent接口,你所要做的就是让你的类继承Component:
编译后,就可以从工具栏中拽入设计窗口,然后你在设计器的属性窗口就可以改变它的名字了。
由于Component实现了IComponent接口,你所要做的就是让你的类继承Component:
public class My : Component
{
}
编译后,就可以从工具栏中拽入设计窗口,然后你在设计器的属性窗口就可以改变它的名字了。
#11
一般控件的名字的属性都是
“(Name)”,但是函数属性名不可以有非法字符“()”显然是非法字符,足见控件的名字和其他的一般属性不一样
#12
学习~
需要自定义个属性,调用这个属性时,值能传进了
#13
up
#14
我把VS 搞死了。。
异常“System.*Exception”在DefaultDomain中发生
异常“System.*Exception”在DefaultDomain中发生
#15
#16
mark xian !you shijian ye haohao xiang xiang !
#17
如果只继承Component类的话,没有界面,拖拽是根本不可能的了。
继承Control! Conrol类本身就有Component,也就不存在我的问题了。
我要实现的功能和ListView添加Items属性相类似。点击添加之后会自动添加一个Item并自动起一个名字,比如items1,当然我需要改这个名字。
#18
没有界面,也可以拖拽。比如Timer,BackGroundWorker这些都是没有界面的组件。
#19
要实现Collection属性,那你添加一个就可以了:
class My : Component
{
private string[] items;
public string[] Items
{
get { return items; }
set { items = value; }
}
}
#20
这样的想法只能想想啊 不好实现吧
#21
还有疑问吗?如果一开始能把问题表达清楚,可以理清你的思维,也可以更快的得到有效的回应。
以下是我描述的全部的代码(新增了两个属性,以避免MyItem出现在工具栏中):
以下是我描述的全部的代码(新增了两个属性,以避免MyItem出现在工具栏中):
class My : Component
{
private MyItem[] items;
public MyItem[] Items { get { return items; } set { items = value; } }
}
[ToolboxItem(false)]
[DesignTimeVisible(false)]
class MyItem : Component
{
//public int Value { get; set; }
}
#22
![[WinF]Propertygrid 如何实现更改对象的名称"(Name)"属性 [WinF]Propertygrid 如何实现更改对象的名称"(Name)"属性](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9hSFIwY0RvdkwzQXVZbXh2Wnk1amMyUnVMbTVsZEM5cGJXRm5aWE12Y0Y5aWJHOW5YMk56Wkc1ZmJtVjBMMkZ6YzJ0NU1USTBMMFZ1ZEhKNVNXMWhaMlZ6THpJd01EZ3hNakF6TCthVmlPYWVuQzVLVUVjPQ%3D%3D.jpg?w=700&webp=1)
我添加的UITypeEditor,现在的效果是点击属性窗口的Item属性就会弹出我自己写的一个窗体,我就是想在这个弹出窗体内修改属性,让我的Items的列表做代码响应改变(永久的;似乎是加这个[TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))])。
水平有限现在只能显示一下,还改不了,而且很容易把VS整出错误,基本是堆栈出错。错误原因还没找到。
#23
本来Array或Collection类型就有UITypeEditor -(System.ComponentModel.Design.ArrayEditor,System.ComponentModel.Design.CollectionEditor)。
你完全可以不用自己写。
如果你要自己写,要理解Visual Studio IDE作为一个设计器所提供的服务。
当你的Component放到设计器上的时候也叫(Sited,中文或许叫进场吧,而恰恰就是IComponent提供了Site这个接口),
通过ISite,你的Component或它所关联的IDesigner,就可以通过GetService来获得设计器所提供的各种服务。
这些服务包括像INameCreationtService(为新建控件取名字的服务),
ITypeDescriptorFilterService(通过该服务为Component加上一些额外的属性,如(name),Locked等等Component运行时没有的属性),
IToolboxService(通过该服务和工具栏交互)
IComponentChangeService(通过服务知道哪些控件被创建了,被删除,被改名了,或被修改了)
等等等等
通过服务不仅可以获得Design View方面的服务,还可以获得Code View方面的服务(可以用来生成和管理代码,Code Serialization),甚至可以获得项目方面的服务。不过,相关的文档并不多见,我建议你先用我在21楼提供的简单写法。
多了这些解释,希望能更好的理解我在10楼提的,只有实现了IComponent,才能放到设计器中的说法。
你完全可以不用自己写。
如果你要自己写,要理解Visual Studio IDE作为一个设计器所提供的服务。
当你的Component放到设计器上的时候也叫(Sited,中文或许叫进场吧,而恰恰就是IComponent提供了Site这个接口),
通过ISite,你的Component或它所关联的IDesigner,就可以通过GetService来获得设计器所提供的各种服务。
这些服务包括像INameCreationtService(为新建控件取名字的服务),
ITypeDescriptorFilterService(通过该服务为Component加上一些额外的属性,如(name),Locked等等Component运行时没有的属性),
IToolboxService(通过该服务和工具栏交互)
IComponentChangeService(通过服务知道哪些控件被创建了,被删除,被改名了,或被修改了)
等等等等
通过服务不仅可以获得Design View方面的服务,还可以获得Code View方面的服务(可以用来生成和管理代码,Code Serialization),甚至可以获得项目方面的服务。不过,相关的文档并不多见,我建议你先用我在21楼提供的简单写法。
多了这些解释,希望能更好的理解我在10楼提的,只有实现了IComponent,才能放到设计器中的说法。
#24
多谢
gomoku
问题基本解决
贴上实例代码
问题基本解决
贴上实例代码
//Item和Item的集合类
/// <summary>
/// Item
/// </summary>
public class MyItem:System.ComponentModel.Component
{
private string s_name;
private string s_value;
public MyItem()
{
//
// TODO: 在此处添加构造函数逻辑
//
this.s_name = string.Empty;
this.s_value = string.Empty;
}
/// <summary>
/// 名字
/// </summary>
public string Name
{
get
{
return this.s_name;
}
set
{
this.s_name = value;
}
}
/// <summary>
/// 数值
/// </summary>
public string Value
{
get
{
return this.s_value;
}
set
{
this.s_name = value;
}
}
}
/// <summary>
/// ItemCollection
/// </summary>
public class ItemCollections:System.Collections.CollectionBase
{
public ItemCollections()
{
}
//这个方法必须有
public MyItem this [int index]
{
get
{
return (MyItem)List[index];
}
set
{
List[index] = value;
}
}
public void Add(MyItem item)
{
this.List.Add(item);
}
public void Remove(MyItem item)
{
this.List.Remove(item);
}
public int IndexOf(MyItem item)
{
return this.List.IndexOf(item);
}
protected override void OnInsert(int index, object value)
{
if(!(value is MyItem))
{
throw new ArgumentException("插入Item不正确","未执行");
}
}
protected override void OnSet(int index, object oldValue, object newValue)
{
if(!(newValue is MyItem))
{
throw new ArgumentException("插入Item不正确","未执行");
}
}
}
#25
//定义一个控件,用来测试
/// <summary>
/// ItemCollection 的摘要说明。
/// </summary>
public class UCItemCollection : System.Windows.Forms.UserControl
{
private ItemCollections m_items;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public UCItemCollection()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
// TODO: 在 InitializeComponent 调用后添加任何初始化
this.m_items = new ItemCollections();
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
[Editor(typeof(System.ComponentModel.Design.CollectionEditor),
typeof(System.Drawing.Design.UITypeEditor))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]//设置设计器是序列化它的内容。
public ItemCollections Items
{
get
{
return this.m_items;
}
}
}
虽然这个方法并不是很好,直接继承类,而不是接口。算是这个方法的美中不足之处吧。
而c#类的继承是只能有一个父类的,不能像C++ 那样多个继承。
要是有个能有接口实现的例子就好了。
#1
class MyClass
{
string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
新增一个public的可读写Name属性即可
{
string name;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
}
新增一个public的可读写Name属性即可
#2
控件的Name是用于生成代码时命名的
而你这个是名称已经确定,要进行修改,不一样
#3
一般的控件Control类都有个“(Name)”属性
你的MyClass类里自己添加一个Name属性就可以了,Control类里的Name属性已经封装好了 所以看不到
你的MyClass类里自己添加一个Name属性就可以了,Control类里的Name属性已经封装好了 所以看不到
#4
把myc1变成 myc2 是修改对象的名字
而Name属性,是对象属性的修改,不一样吧
而Name属性,是对象属性的修改,不一样吧
#5
.net 的SDK上说要继承ISite接口,还要设置关联的 IContainer,比较生涩难懂。
谁有例子啊?
谁有例子啊?
#6
I would suggest you don't do it.
Your PropertyGrid works in the runtime but the code serialization (generating code in the Form1.Designer.cs) happens in the design time.
#7
这个名字是对象的名称,就跟变量一样,是编译时使用的,不可以动态更改!~~
2#的name是类的成员,就可以跟其它成员一样赋值了
2#的name是类的成员,就可以跟其它成员一样赋值了
#8
即使Control对象的Name也只是在设计时可以修改。
你可以尝试在PropertyGrid中编辑一个自带的Control,比如TextBox。但是控件的Name属性并不会显示在PropertyGrid中。
你可以尝试在PropertyGrid中编辑一个自带的Control,比如TextBox。但是控件的Name属性并不会显示在PropertyGrid中。
#9
当然是在设计时修改,
我就是自定义了一个控件有个Items属性,在设计时点击Items属性时弹出一个窗体,然后可以编辑这个Items列表,就像ListView控件的Items属性一样
#10
一个类如果是IComponent,那么它就可以放入设计窗口中。(name)并不是真正类的属性,而是设计器通过IExtenderProviderService服务提供的扩展属性。
由于Component实现了IComponent接口,你所要做的就是让你的类继承Component:
编译后,就可以从工具栏中拽入设计窗口,然后你在设计器的属性窗口就可以改变它的名字了。
由于Component实现了IComponent接口,你所要做的就是让你的类继承Component:
public class My : Component
{
}
编译后,就可以从工具栏中拽入设计窗口,然后你在设计器的属性窗口就可以改变它的名字了。
#11
一般控件的名字的属性都是
“(Name)”,但是函数属性名不可以有非法字符“()”显然是非法字符,足见控件的名字和其他的一般属性不一样
#12
学习~
需要自定义个属性,调用这个属性时,值能传进了
#13
up
#14
我把VS 搞死了。。
异常“System.*Exception”在DefaultDomain中发生
异常“System.*Exception”在DefaultDomain中发生
#15
#16
mark xian !you shijian ye haohao xiang xiang !
#17
如果只继承Component类的话,没有界面,拖拽是根本不可能的了。
继承Control! Conrol类本身就有Component,也就不存在我的问题了。
我要实现的功能和ListView添加Items属性相类似。点击添加之后会自动添加一个Item并自动起一个名字,比如items1,当然我需要改这个名字。
#18
没有界面,也可以拖拽。比如Timer,BackGroundWorker这些都是没有界面的组件。
#19
要实现Collection属性,那你添加一个就可以了:
class My : Component
{
private string[] items;
public string[] Items
{
get { return items; }
set { items = value; }
}
}
#20
这样的想法只能想想啊 不好实现吧
#21
还有疑问吗?如果一开始能把问题表达清楚,可以理清你的思维,也可以更快的得到有效的回应。
以下是我描述的全部的代码(新增了两个属性,以避免MyItem出现在工具栏中):
以下是我描述的全部的代码(新增了两个属性,以避免MyItem出现在工具栏中):
class My : Component
{
private MyItem[] items;
public MyItem[] Items { get { return items; } set { items = value; } }
}
[ToolboxItem(false)]
[DesignTimeVisible(false)]
class MyItem : Component
{
//public int Value { get; set; }
}
#22
![[WinF]Propertygrid 如何实现更改对象的名称"(Name)"属性 [WinF]Propertygrid 如何实现更改对象的名称"(Name)"属性](https://image.shishitao.com:8440/aHR0cHM6Ly93d3cuaXRkYWFuLmNvbS9nby9hSFIwY0RvdkwzQXVZbXh2Wnk1amMyUnVMbTVsZEM5cGJXRm5aWE12Y0Y5aWJHOW5YMk56Wkc1ZmJtVjBMMkZ6YzJ0NU1USTBMMFZ1ZEhKNVNXMWhaMlZ6THpJd01EZ3hNakF6TCthVmlPYWVuQzVLVUVjPQ%3D%3D.jpg?w=700&webp=1)
我添加的UITypeEditor,现在的效果是点击属性窗口的Item属性就会弹出我自己写的一个窗体,我就是想在这个弹出窗体内修改属性,让我的Items的列表做代码响应改变(永久的;似乎是加这个[TypeConverter(typeof(System.ComponentModel.ExpandableObjectConverter))])。
水平有限现在只能显示一下,还改不了,而且很容易把VS整出错误,基本是堆栈出错。错误原因还没找到。
#23
本来Array或Collection类型就有UITypeEditor -(System.ComponentModel.Design.ArrayEditor,System.ComponentModel.Design.CollectionEditor)。
你完全可以不用自己写。
如果你要自己写,要理解Visual Studio IDE作为一个设计器所提供的服务。
当你的Component放到设计器上的时候也叫(Sited,中文或许叫进场吧,而恰恰就是IComponent提供了Site这个接口),
通过ISite,你的Component或它所关联的IDesigner,就可以通过GetService来获得设计器所提供的各种服务。
这些服务包括像INameCreationtService(为新建控件取名字的服务),
ITypeDescriptorFilterService(通过该服务为Component加上一些额外的属性,如(name),Locked等等Component运行时没有的属性),
IToolboxService(通过该服务和工具栏交互)
IComponentChangeService(通过服务知道哪些控件被创建了,被删除,被改名了,或被修改了)
等等等等
通过服务不仅可以获得Design View方面的服务,还可以获得Code View方面的服务(可以用来生成和管理代码,Code Serialization),甚至可以获得项目方面的服务。不过,相关的文档并不多见,我建议你先用我在21楼提供的简单写法。
多了这些解释,希望能更好的理解我在10楼提的,只有实现了IComponent,才能放到设计器中的说法。
你完全可以不用自己写。
如果你要自己写,要理解Visual Studio IDE作为一个设计器所提供的服务。
当你的Component放到设计器上的时候也叫(Sited,中文或许叫进场吧,而恰恰就是IComponent提供了Site这个接口),
通过ISite,你的Component或它所关联的IDesigner,就可以通过GetService来获得设计器所提供的各种服务。
这些服务包括像INameCreationtService(为新建控件取名字的服务),
ITypeDescriptorFilterService(通过该服务为Component加上一些额外的属性,如(name),Locked等等Component运行时没有的属性),
IToolboxService(通过该服务和工具栏交互)
IComponentChangeService(通过服务知道哪些控件被创建了,被删除,被改名了,或被修改了)
等等等等
通过服务不仅可以获得Design View方面的服务,还可以获得Code View方面的服务(可以用来生成和管理代码,Code Serialization),甚至可以获得项目方面的服务。不过,相关的文档并不多见,我建议你先用我在21楼提供的简单写法。
多了这些解释,希望能更好的理解我在10楼提的,只有实现了IComponent,才能放到设计器中的说法。
#24
多谢
gomoku
问题基本解决
贴上实例代码
问题基本解决
贴上实例代码
//Item和Item的集合类
/// <summary>
/// Item
/// </summary>
public class MyItem:System.ComponentModel.Component
{
private string s_name;
private string s_value;
public MyItem()
{
//
// TODO: 在此处添加构造函数逻辑
//
this.s_name = string.Empty;
this.s_value = string.Empty;
}
/// <summary>
/// 名字
/// </summary>
public string Name
{
get
{
return this.s_name;
}
set
{
this.s_name = value;
}
}
/// <summary>
/// 数值
/// </summary>
public string Value
{
get
{
return this.s_value;
}
set
{
this.s_name = value;
}
}
}
/// <summary>
/// ItemCollection
/// </summary>
public class ItemCollections:System.Collections.CollectionBase
{
public ItemCollections()
{
}
//这个方法必须有
public MyItem this [int index]
{
get
{
return (MyItem)List[index];
}
set
{
List[index] = value;
}
}
public void Add(MyItem item)
{
this.List.Add(item);
}
public void Remove(MyItem item)
{
this.List.Remove(item);
}
public int IndexOf(MyItem item)
{
return this.List.IndexOf(item);
}
protected override void OnInsert(int index, object value)
{
if(!(value is MyItem))
{
throw new ArgumentException("插入Item不正确","未执行");
}
}
protected override void OnSet(int index, object oldValue, object newValue)
{
if(!(newValue is MyItem))
{
throw new ArgumentException("插入Item不正确","未执行");
}
}
}
#25
//定义一个控件,用来测试
/// <summary>
/// ItemCollection 的摘要说明。
/// </summary>
public class UCItemCollection : System.Windows.Forms.UserControl
{
private ItemCollections m_items;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
public UCItemCollection()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
// TODO: 在 InitializeComponent 调用后添加任何初始化
this.m_items = new ItemCollections();
}
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要使用代码编辑器
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
}
#endregion
[Editor(typeof(System.ComponentModel.Design.CollectionEditor),
typeof(System.Drawing.Design.UITypeEditor))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]//设置设计器是序列化它的内容。
public ItemCollections Items
{
get
{
return this.m_items;
}
}
}
虽然这个方法并不是很好,直接继承类,而不是接口。算是这个方法的美中不足之处吧。
而c#类的继承是只能有一个父类的,不能像C++ 那样多个继承。
要是有个能有接口实现的例子就好了。