6

我面临一个我不知道如何解决的问题,希望社区可以提供帮助。

我正在编写一个管理“Lead”对象的应用程序。(这些是销售线索。)我的程序的一部分将从文本文件中导入线索。现在,文本文件包含许多潜在的潜在客户,其中一些我想要导入,而另一些我不想导入。

为了便于编程(和使用),我将文本文件解析为 List<Lead> 对象,并使用 DataGridView 通过设置 DataGridView 的 DataSource 属性来显示潜在客户。

我想要做的是在网格中添加一个名为“导入”的列,并带有一个复选框,用户可以选中该复选框以指示是否应导入每个潜在客户。

我的第一个想法是从 Lead 派生一个类:

public Class LeadWithImportCheckbox : Lead
{
   bool bImport = false;

public bool Import { get { return bImport;} set { bImport = value;} } }

但是,解析引擎会返回 Lead 对象的列表。我不能将潜在客户转换为 LeadWithImportCheckbox。这失败了:

LeadWithImportCheckbox newLead = (LeadWithImportCheckbox)LeadFromParsingEngine;
这是一个无效的演员表。

我看到的另一个选项是为 LeadWithImportCheckbox 创建一个构造函数:

public LeadWithImportCheckbox(Lead newlead)
{
  base.Property1 = newlead.Property1;
  base.Property2 = newlead.Property2;
  ....
  base.Property_n = newlead.Property_n;
}
这是有问题的,原因有两个。一,Lead 对象有几十个属性,编写这个构造函数是一个 PITA。

但更糟糕的是,如果我更改了 Lead 的底层结构,我需要记得返回并更改 LeadWithImportCheckbox 的构造函数。这对我的代码维护是一个危险。

有没有更好的方法来实现我的目标?

4

11 回答 11

7

或者,为了避免 PITA 方面,使用反射......(试试这个......)

编辑:使用属性,而不是我最初写的字段...

public class NewLead : Lead
{
    public bool Insert;
    public NewLead(Lead lead, bool insert)
    {
        Insert = insert;
        foreach (PropertyInfo pi in typeof(Lead).GetProperties())
            GetType().GetProperty(pi.Name).SetValue
               (this, pi.GetValue(lead,null), null);
    }
}
于 2009-07-15T19:22:36.600 回答
4
public class LeadListItem
{
    public Lead Lead { get; set; }
    public bool ShouldImport { get; set; }
}

即不要复制 Lead 对象的内容,只需将对它的引用存储在新的 LeadListItem 对象中,这会在原始对象“外部”添加额外的信息。

如果您希望 Lead 的属性出现在网格中,几乎可以肯定有一种方法可以做到这一点。为什么不问这个问题,而不是因为我告诉你这个问题的正确答案而对我投反对票!

于 2009-07-15T19:01:58.903 回答
3

您可能错过的几个选项:

  • 您可以将 Lead 对象本身更新为具有 Import 属性(默认为 false)。
  • 您可以让您的“ImportLead”对象将潜在客户视为有效负载(如果您愿意,甚至可以将其设为通用),因此您不需要大的构造函数。
  • 构建一个新的 Lead 对象列表或可枚举的对象,其中仅包含您首先要导入的对象。
于 2009-07-15T19:02:25.907 回答
1

您想要做的是在您的网格上显示复选框列,而不是让它与您的潜在客户对象完全相关。您使用标记的列(以及可能的原始列表)来构建一组新的列表,这将是您的导入列表。

然后处理您希望对新创建的列表执行的任何操作。

编辑:使用列表时要注意的一件事是,每个类对象实际上只是指向该类的指针,因此如果您使用原始列表并执行以下操作:

List<Lead> Importable = new List<Lead>();

for(int i=0, i++, i<viewGrid.Count)
    if(viewGrid[i].CheckedColumn.Checked)
        Importable.Add(OriginalList[i]);

该对象将存在于两个列表中,如果您在任一列表中编辑潜在客户的数据,两者都将被更改。

于 2009-07-15T19:00:22.137 回答
1

如果要向下转换的对象确实是该类型的对象,则只能向下转换。

解决问题的更简单方法是使用 DisplayLead 类,例如:

  public class DisplayLead {
      Lead lead;
      bool bImport;
  }

这也将帮助您将存储的数据与其在 GUI 中的表示分离。

于 2009-07-15T19:03:29.167 回答
1

我不能对它不是的东西感到沮丧。如果对象被实例化为Lead,那么它不能向下转换为任何派生类。如果它被实例化为 aLeadWithImportCheckbox然后返回到您的代码中Lead,那么您可以向下转换它。

Protip:在运行时使用is运算符检查类型。

于 2009-07-15T19:08:03.273 回答
1

有很多方法可以做到这一点,但由于你所说的,“正确”的方法会弹出,在这里:

为了便于编程(和使用),我将文本文件解析为 List 对象,并使用 DataGridView 通过设置 DataGridView 的 DataSource 属性来显示线索。

我想要做的是在网格中添加一个名为“导入”的列,并带有一个复选框,用户可以选中该复选框以指示是否应导入每个潜在客户。

您的Lead对象独立存在,并且您希望将一些元数据附加到它 - 您不想创建另一个Lead分类(即LeadWithImportCheckbox 类)。

所以,在你的情况下,最好的方法是有一个像这样的类:

public class LeadInfo 
{
    private Lead lead;
    private bool shouldImport;

    public LeadInfo(Lead lead)
    {
        this.lead = lead;
        this.ShouldImport = false;
    }

    public bool ShouldImport 
    { 
        get { return shouldImport;  }
        set { shouldImport = value; }  
    }
}

当您想向列表中添加更多元数据时,这将很好地扩展,例如如果您想每周向自己发送有关它们的电子邮件提醒。

于 2009-07-15T19:15:56.927 回答
1

我已经看到列出的正确解决方案很多次了,我感觉就像是再次发布它一样,但解决这个问题的最佳方法是为包含导入标志的 Lead 对象编写一个包装器。

如果 Lead 对象的属性未出现在 GridView 中,因为您正在对对象进行数据绑定,则编写传递属性以反映包装对象上的 Lead 属性。

问题是您希望向用户显示的内容不是数据模型的固有部分。答案是在将数据呈现给用户之前对其进行包装,这样您就可以在不更改底层模型的情况下控制他们看到的内容。

如果您担心 Lead 对象将来会更改很多次以至于对包装器的更改会很麻烦,您可以查看基于 Lead 对象的动态代码生成,该对象将自动生成具有相同字段的包装器对象Lead 对象加上导入标志。虽然坦率地说,这比你可能需要的这么简单的事情要多得多。

于 2009-07-15T19:40:06.737 回答
0

作为一种快速而肮脏的解决方案,您可以将“复选框”对象创建为包含 Lead 实例的不同对象。

public GridLead {
   public bool Import { get; set; }
   public Lead Lead { get; set; }
}

这样,您可以轻松地向该对象添加更多“网格”属性,同时始终保留对潜在客户详细信息的引用,而无需将属性克隆到其中。

于 2009-07-15T19:05:10.723 回答
0

建议您尝试修改(升级)您导入的潜在客户对象。

尝试从此处的示例开始...

于 2009-07-15T19:06:04.700 回答
0

如果您的 Lead 类有一个复制构造函数(例如“Lead(Lead (Lead otherLead)”),LeadWithImportCheckbox 将继承它,您可以在 LeadWithImportCheckbox 构造函数中调用基本 Lead 构造函数 - 因此无需 LeadWithImportCheckbox 了解 Lead 的详细信息.

于 2009-07-15T19:09:17.750 回答