65.9K
CodeProject 正在变化。 阅读更多。
Home

根据 XML 架构从任何对象生成 ListViewItem

starIconstarIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIcon

2.89/5 (5投票s)

2004年6月20日

2分钟阅读

viewsIcon

45365

downloadIcon

255

如何使用 XML 架构从对象生成 ListViewItem。

引言

在本文中,我将解释如何从对象生成 ListViewItem。基本思路是创建一个包含方法的类,我们可以将任何对象传递给该方法,并获得一个 ListViewItem 作为结果。

入门

那么,让我们开始编写代码吧。

public class MyListViewItem : System.Windows.Forms.ListViewItem

{ 
 public MyListViewItem() { }
 public MyListViewItem CreateItem(object obj) { return this; }
}

这将是我们的类。我们只需要一个名为 CreateItem 的方法,该方法应该返回一个 ListViewItem

使用反射获取对象信息?

由于我们对传递到 CreateItem 方法的对象一无所知,因此我们实际上无法对该对象做太多事情,对吧?

假设我们传递到 CreateItem 的对象是由以下类创建的

public class ClassA
{
  private string author;
  public ClassA()
  {
  }
  public string Author
  {
    get { return this.author; }
    set { this.author = value; }
  }
  public int Number(int nr)
  {
    return 2*nr;
  }
}

第一次尝试是简单地根据对象公开的所有属性填充 ListViewItem。但是,如果我们只对某些属性感兴趣呢?我们需要指定我们期望包含在 ListViewItem 中的数据,以及我们的 CreateItem 方法可以在哪里找到这些信息。

我们使用 XML 文件来指定这些信息。我们的文件将如下所示

我们需要一些 XML

<?xml version="1.0" encoding="utf-8"?>
<ListViewItem>
<item Name="Author" Type="Property" Parameter=""></item>
<item Name="Number" Type="Method" Parameter="2"></item>
<item Name="Number" Type="Method" Parameter="4"></item>
</ListViewItem>

让我们扩展我们的类,以便能够使用这些信息。

我们的小助手类

首先,我们创建一个小助手类,它可以包含来自 XML 文件中的信息。

private class MethodInformation
{
  private string name;
  private string type;
  private string parameter;
  public MethodInformation()
  {
  }

  public string Name
  {
    get{return this.name;}
    set{this.name = value;}
  }

  public string Type
  {
    get{return this.type;}
    set{this.type = value;}
  }
  public string Parameter
  {
    get{return this.parameter;}
    set{this.parameter = value;}
  }
}

让我们使用它

现在,让我们使用助手类和 XML 文件中的信息。我们将以下代码放在 MyListViewItem 类的构造函数中

//ArrayList to hold the information about our item

_methodInformation = new ArrayList();

//read the XML Schema so we know how to build the ListViewItem
DataSet ds = new DataSet();
ds.ReadXml("item.xml");

foreach(DataRow dr in ds.Tables["item"].Rows)
{
  //create a MethodInformation Object
  MethodInformation mi = new MethodInformation();
  mi.Name = dr["Name"].ToString();
  mi.Type = dr["Type"].ToString();
  mi.Parameter = new object[] {dr["Parameter"].ToString()};
  _methodInformation.Add(mi);
}

现在,我们的 CreateItem 方法可以使用这些信息,并通过反射调用方法来创建一个 ListViewItem

使用反射和 XML 信息创建 Item 方法

public MyListViewItem CreateItem(object obj)
{
  int itemCounter=0; //need to know if it is a subitem
  string methodName;
  Type myType = obj.GetType();

  foreach(MethodInformation itemInfo in _methodInformation)
  {
    //check if we have a property because we 
    //have to add a get_ prefix in this case

    if(itemInfo.Type=="Property")
    {
      methodName = "get_"+itemInfo.Name;
    }
    else if(itemInfo.Type=="Method")
    {
      methodName = itemInfo.Name;
    }
    else
    {
      throw new Exception("Unkown Type." + 
        " Only Method or Property are valids type");
    }
    MethodInfo mi = myType.GetMethod(methodName);

    //check if we have parameters
    object[] parameter = null;
    if(itemInfo.Parameter != "")
    { 
       ParameterInfo[] pi = mi.GetParameters();
       Type parType = pi[0].ParameterType;
       parameter = new Object[1];
       TypeConverter tc = TypeDescriptor.GetConverter(parType);
       parameter[0] = tc.ConvertFromString(itemInfo.Parameter);
     }

     if(itemCounter==0)
     {
       this.Text = System.Convert.ToString(mi.Invoke(obj,parameter));
       itemCounter++;
     }
     else
     {
       this.SubItems.Add(System.Convert.ToString(mi.Invoke(obj,parameter)));
     }
  }
  //return the ListViewItem
  return this;
}

最后说明

我在几个项目中使用了这种方法,它为我节省了大量的工作。请留下您的评论。谢谢!

历史

  • 2006年04月20日 版本 1.0
  • 2006年06月24日 版本 1.1 - 更新以处理非字符串参数(感谢 mav.northwind)
© . All rights reserved.