问题一: 自已写到一个类, 其中有一个属性是字串型, 是用来保存一个文件名的, 这个类需要客户在使用时能在PropertyGrid里runtime修改内容, 友好的方式当然是让客户在PropertyGrid里可以有一个"..."的按钮, 点一下之后打开一个openfiledialog, 选择一个文件之后返回, 文件的全路径就放在属性值的框里了. 如何达到这个目的?
比如这个类如下:
public class class1
{
public class1()
{
}
// 

private string _s;
public string s
{
get{return this._s;}
set{this._s = value;}
}
}

这样的话在PropertyGrid里s属性的后面只有一个简简单单的编辑框, 为了使s的编辑区可以出现一个"..." 按钮, 并且可以用文件打开对话框选择文件, 可以使用EditorAttribute属性对这个属性进行标记:

[Editor(typeof(System.Windows.Forms.Design.FileNameEditor),
typeof(System.Drawing.Design.UITypeEditor))]
public string S
{
get{return this._s;}
set{this._s = value;}
}
FileNameEditor类提供了一个打开文件的对话框, 以编辑属性值, 这个类派生于UITypeEditor类, UITypeEditor是所有设计时界面的基类.
这样就可以达到有文件对话框的目的了, 但是如果想要指定只选择某一种文件类型, 如"WAV"文件, 那就得派生FileNameEditor, 重写有关的方法.
public class SoundFileEditor:System.Windows.Forms.Design.FileNameEditor
{
protected override void InitializeDialog(OpenFileDialog openFileDialog)
{
base.InitializeDialog (openFileDialog);
// 在基类初始代完对话框之后, 可以对这个对话框做一些手脚.
openFileDialog.Filter = "wav and vox file(*.wav, *.vox)|*.wav;*.vox|wav files (*.wav)|*.wav|vox files (*.vox)|*.vox|All files (*.*)|*.*";
}
}
再把Class1中的S的EditorAttribute改为派生的这个子类, 现在对话框里的文件过滤器改为你想要的了.
你甚至可以从UITypeEditor自己重新派生一个子类出来, 自己写一个能弹出"保存文件"对话框的UI编辑类. 注意在重写UITypeEditor的
public virtual new System.Object EditValue ( System.ComponentModel.ITypeDescriptorContext context , System.IServiceProvider provider , System.Object value )方法, 注意返回自己需要对象就可以了.
问题二: 如何设定一个类的"默认值编辑器"?
例如: 比如有一个类叫SoundFileName专门用来处理声音文件名, 如果Class1中有一个属性FileName是SoundFileName类型, 这个属性在PropertyGrid里编辑器里默认情况下是没有办法编辑的, 为了让SoundFileName类可以在propertyGrid里可以编辑, 必须对SoundFileName进行属性标志, 指定一个默认的编辑器. 假定我们还是希望通过"打开文件"对话框来指定一个文件的方式生成一个SoundFileName对象, 那么我们可以写一个从UITypeEditor中直接或间接派生的子类, 以完成编辑对象内容的操作.
如下代码所示, 这个专门编辑SoundFileName对象的类叫SoundfileNameEditor, 我们随后实现它, 现在先看SoundFileName的实现. 注意class之前的标记:
这里定义了此类的值编辑器为SoundFileNameEditor类, 这个类我们需要从UITypeEditor或是其子类中派生出来, 重写其EditValue方法, 以可以返回一个SoundFileName对象.
为了省事, 我就不再从UITypeEditor派生了, 而是从SoundFileEditor派生, SoundFileEditor已经把文件名过滤器修改了, 但是SoundFileEditor的EditValue返回的是一个字串, 这次只要修改SoundFileEditor的EditValue的值就可以了.
public class SoundFileNameEditor: SoundFileEditor
{
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
SoundFileName sfn = value as SoundFileName;
return new SoundFileName(base.EditValue (context, provider, sfn==null?"":sfn.FileName) as string);
}
}
注意, 这个EditValue总是会返回一个新的对象, 把从前的对象扔掉, 你可以通过判断value是不是null来决定是否新建一个对象, 还是只是修正一下其中的文件名, 这里不再多说了.
现在你在PropertyGrid里可以编辑SoundFileNmae对象了, 编辑器弹出一个打开文件对话框, 选择了文件之后, 根据文件名建立了一个SoundFileName对象.
最后提示一下, 不知道你注意到了没有, 当选择了文件名建立了一个SoundFileName对象之后, 在编辑框里的内容是"testanything.SoundFileName", 用户看起来不会太高兴, 也不直观, 这个也好办, 你可以重写SoundFileName的ToString()方法来用任何方式显示你想要内容.
比如这个类如下:

















这样的话在PropertyGrid里s属性的后面只有一个简简单单的编辑框, 为了使s的编辑区可以出现一个"..." 按钮, 并且可以用文件打开对话框选择文件, 可以使用EditorAttribute属性对这个属性进行标记:









这样就可以达到有文件对话框的目的了, 但是如果想要指定只选择某一种文件类型, 如"WAV"文件, 那就得派生FileNameEditor, 重写有关的方法.
public class SoundFileEditor:System.Windows.Forms.Design.FileNameEditor
{
protected override void InitializeDialog(OpenFileDialog openFileDialog)
{
base.InitializeDialog (openFileDialog);
// 在基类初始代完对话框之后, 可以对这个对话框做一些手脚.
openFileDialog.Filter = "wav and vox file(*.wav, *.vox)|*.wav;*.vox|wav files (*.wav)|*.wav|vox files (*.vox)|*.vox|All files (*.*)|*.*";
}
}
再把Class1中的S的EditorAttribute改为派生的这个子类, 现在对话框里的文件过滤器改为你想要的了.
你甚至可以从UITypeEditor自己重新派生一个子类出来, 自己写一个能弹出"保存文件"对话框的UI编辑类. 注意在重写UITypeEditor的

问题二: 如何设定一个类的"默认值编辑器"?
例如: 比如有一个类叫SoundFileName专门用来处理声音文件名, 如果Class1中有一个属性FileName是SoundFileName类型, 这个属性在PropertyGrid里编辑器里默认情况下是没有办法编辑的, 为了让SoundFileName类可以在propertyGrid里可以编辑, 必须对SoundFileName进行属性标志, 指定一个默认的编辑器. 假定我们还是希望通过"打开文件"对话框来指定一个文件的方式生成一个SoundFileName对象, 那么我们可以写一个从UITypeEditor中直接或间接派生的子类, 以完成编辑对象内容的操作.
如下代码所示, 这个专门编辑SoundFileName对象的类叫SoundfileNameEditor, 我们随后实现它, 现在先看SoundFileName的实现. 注意class之前的标记:
[EditorAttribute(typeof(SoundFileNameEitor),
typeof (System.Drawing.Design.UITypeEditor))]
public class SoundFileName
{
private string _filename;
public string FileName
{
get{return _filename;}
}
public SoundFileName(string s)
{
this._filename = s;
}
}
typeof (System.Drawing.Design.UITypeEditor))]
public class SoundFileName
{
private string _filename;
public string FileName
{
get{return _filename;}
}
public SoundFileName(string s)
{
this._filename = s;
}
}
这里定义了此类的值编辑器为SoundFileNameEditor类, 这个类我们需要从UITypeEditor或是其子类中派生出来, 重写其EditValue方法, 以可以返回一个SoundFileName对象.
为了省事, 我就不再从UITypeEditor派生了, 而是从SoundFileEditor派生, SoundFileEditor已经把文件名过滤器修改了, 但是SoundFileEditor的EditValue返回的是一个字串, 这次只要修改SoundFileEditor的EditValue的值就可以了.
public class SoundFileNameEditor: SoundFileEditor
{
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
SoundFileName sfn = value as SoundFileName;
return new SoundFileName(base.EditValue (context, provider, sfn==null?"":sfn.FileName) as string);
}
}
注意, 这个EditValue总是会返回一个新的对象, 把从前的对象扔掉, 你可以通过判断value是不是null来决定是否新建一个对象, 还是只是修正一下其中的文件名, 这里不再多说了.
现在你在PropertyGrid里可以编辑SoundFileNmae对象了, 编辑器弹出一个打开文件对话框, 选择了文件之后, 根据文件名建立了一个SoundFileName对象.
最后提示一下, 不知道你注意到了没有, 当选择了文件名建立了一个SoundFileName对象之后, 在编辑框里的内容是"testanything.SoundFileName", 用户看起来不会太高兴, 也不直观, 这个也好办, 你可以重写SoundFileName的ToString()方法来用任何方式显示你想要内容.
分类:
技术
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架