科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件编写与.NET属性窗口交互的RAD组件(三)

编写与.NET属性窗口交互的RAD组件(三)

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

编写和显示订制的类型

作者: 来源:中国IT实验室 2008年6月6日

关键字: 组件 交互 VB vb.net Windows

  • 评论
  • 分享微博
  • 分享邮件
编写和显示订制的类型
  
  属性窗口中的编辑有如下三种工作方式:一,有些场合可以作为字符串来编辑,然后由TypeConverter来实现类型的转换。二,可以显示一个下拉列表来选择值。三,一个省略按钮提供其他的UI界面来编辑值,比如FileDialog和FontPicker。我们已经讲过了字符串形式,接着我们就来看下拉列表。
  
  .NET framework已经包含了好几种下拉列表的例子,如Color,AccessibleRole,Dock等属性。我们从下图可以看到下拉列表的具体实现。
   
  图4. 下拉列表编辑器
  
  实现下拉的工作同样是由TypeConverter来定义。如果看TypeConverter的说明,可以看到有三个虚函数来实现这个功能:GetStandardValuesSupported(),GetStandardValues()和GetStandardValuesExclusive()。重载这些方法,我们可以为属性提供预先定义好的值列表。实际上,是TypeConverter实现了下拉列表中的枚举值。属性窗口自己本身并没有代码来处理这种下拉列表的编辑,而仅仅是使用TypeConverter的方法。
  
  举个例来说,我们有一个包含Relation属性的FamilyMember组件,允许用户选择与其他人之间的关系。如果要使设计时界面更友好的话,属性窗口应该使用下拉列表来提供一些常用值的选择:如mother,father,daughter和sister等。除了提供的常用值之外,组件使用者也可以输入其他的表示关系的字符串值。
  
  public class FamilyMember : Component
  
  {
  
  private string relation = "Unknown";
  
  [TypeConverter(typeof(RelationConverter)),Category("Details")]
  
  public string Relation
  
  {
  
  get { return relation;}
  
  set { this.relation = value;}
  
  }
  
  }
  
  internal class RelationConverter : StringConverter
  
  {
  
  private static StandardValuesCollection defaultRelations =
  
  new StandardValuesCollection(
  
  new string[]{"Mother", "Father", "Sister",
  
  "Brother", "Daughter", "Son",
  
  "Aunt", "Uncle", "Cousin"});
  
  public override bool GetStandardValuesSupported(
  
  ITypeDescriptorContext context)
  
  {
  
  return true;
  
  }
  
  public override bool GetStandardValuesExclusive(
  
  ITypeDescriptorContext context)
  
  {
  
  // returning false here means the property will
  
  // have a drop down and a value that can be manually
  
  // entered.
  
  return false;
  
  }
  
  public override StandardValuesCollection GetStandardValues(
  
  ITypeDescriptorContext context)
  
  {
  
  return defaultRelations;
  
  }
  
  }
  
  不过如何做一个更加定制化的UI呢?我们可以使用UITypeEditor类。UITypeEditor类包括了在显示属性或者是编辑属性(比如下拉列表和省略按钮)时可以由属性窗口调用的方法。
  
  一些类似于Image,Color,Font.Name的属性类型会在属性值的左边有一个小的图形化表示,这是通过重载UITypeEditor的PaintValue方法实现的。当属性窗口得到定义了编辑器的属性值的时候,它就提供给编辑器一个矩形框对象(Rectangle)和画图的对象(Graphic),他们都包含在PaintValue方法的事件参数PaintValueEventArgs中。举个例子来说,我们有一个Grade类需要有图形化的表示。下面就是我们的Grade类。
  
  [Editor(typeof(GradeEditor), typeof(System.Drawing.Design.UITypeEditor))]
  
  [TypeConverter(typeof(GradeConverter))]
  
  public struct Grade
  
  {
  
  private int grade;
  
  public Grade(int grade)
  
  {
  
  this.grade = grade;
  
  }
  
  public int Value
  
  {
  
  get
  
  {
  
  return grade;
  
  }
  
  }
  
  }
  
  当我们输入一个年龄的时候,我们可以看到左边的一个图形表示。
  
  图5. 输入年龄
  
  实现它并不困难。注意到赋给Grade类的EditorAttribute特性,它就是下面的这个类:
  
  public class GradeEditor : UITypeEditor
  
  {
  
  public override bool GetPaintValueSupported(
  
  ITypeDescriptorContext context)
  
  {
  
  // let the property browser know we'd like
  
  // to do custom painting.
  
  return true;
  
  }
  
  public override void PaintValue(PaintValueEventArgs pe)
  
  {
  
  // choose the right bitmap based on the value
  
  string bmpName = null;
  
  Grade g = (Grade)pe.Value;
  
  if (g.Value > 80)
  
  {
  
  bmpName = "best.bmp";
  
  }
  
  else if (g.Value > 60)
  
  {
  
  bmpName = "ok.bmp";
  
  }
  
  else
  
  {
  
  bmpName = "bad.bmp";
  
  }
  
  // draw that bitmap onto the surface provided.
  
  Bitmap b = new Bitmap(typeof(GradeEditor), bmpName);
  
  pe.Graphics.DrawImage(b, pe.Bounds);
  
  b.Dispose();
  
  }
  
  }
  
  像我们上面提到的,UITypeEditor可以实现属性的下拉选择和弹出对话框选择。后面的例子会包括这样的代码。如果想知道进一步的信息的话,就要参考UITypeEditor.GetEditStyle和UITypeEditor.EditValue方法以及IWindowsFormsEditorService接口。
    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章