【问题标题】:Intellisense for DataGridView column names when using a List<T> as the Datasource使用 List<T> 作为数据源时 DataGridView 列名的智能感知
【发布时间】:2011-08-31 19:52:57
【问题描述】:

我有一个 DataGridView,它有 4 列需要格式化。此 DataGridView 的数据源是来自具有 4 个属性的类的对象的通用列表。

在设计时,如何使用 intelisense 来指定列?

DataGridView dgv = new DataGridView();
List<MyDataRow> myDataList = new List<MyDataRow>();

   // List is populated in this section of code...

dgv.DataSource = myDataList;
dgv.Columns["ALongDescriptiveNameThatCouldEasilyBeMistyped"].Width = 80;    .

   // dgv is added to a form and displayed in this section of code

public class MyDataRow
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public double ALongDescriptiveNameThatCouldEasilyBeMistyped { get; set; }
    public int YearsOfService { get; set; }
    public int MonthsOfService { get; set; }
}

【问题讨论】:

    标签: c# visual-studio datagridview


    【解决方案1】:

    您可以使用以下类,该类包含使用表达式树作为参数的方法,以根据 lambda 表达式确定成员名称:

    public class MemberHelper<T> where T : class
    {
        public string GetName<U>(Expression<Func<T, U>> expression)
        {
            MemberExpression memberExpression = expression.Body as MemberExpression;
            if(memberExpression != null)
                return memberExpression.Member.Name;
    
            throw new InvalidOperationException("Member expression expected");
        }
    }
    

    你可以使用这样的方法:

    MemberHelper<MyDataRow> memberHelper = new MemberHelper<MyDataRow>();
    dgv.Columns[memberHelper.GetName(d => d.FirstName)].Width = 80; 
    

    【讨论】:

    • 我真的很喜欢这种方法。我有许多包含许多列的类,这些列在开发过程中经常更改。 StackOverflow 的成员很棒。
    • @DarwinIcesurfer - 需要注意的一点是,这种方法比使用字符串或整数访问列集合要慢得多。但我想强类型代码在运行时的性能损失超过了小幅性能损失,这并不是一种不常见的方法,最显着地用于 ASP.NET MVC (Html Helpers)。很高兴它有帮助。
    【解决方案2】:

    Intellisense 无济于事,因为 Columns 只是 int/string 索引器。您可以在属性上使用属性和一些反射,然后 Linq 查询构造字符串数组,其中包含用特定属性装饰的属性名称,但在您的情况下可能不值得。

    【讨论】:

      【解决方案3】:

      最简单的方法是声明包含列名的枚举,并指定从 0 到 N 的整数值,并将该枚举用于基于索引的 DataGrid 列的访问。

      类似这样的伪代码:

      enum ColumnNames
      {
          ColumnName1 = 0, 
          ColumnName2 = 1,
          ColumnName3 = 2,
           .....
            .....
      }
      

      【讨论】:

      • 谢谢@Tigran 这种方法可能会有所帮助。但是,如果重构属性名称,则枚举不会更改。如果在类中间添加另一个属性,则还需要修改枚举。我想我可以将枚举放在班级旁边......但是没有更简单的方法吗?
      • @DawwinIcesurfer:在这种情况下,不要真的认为你可以做你想做的事。原因,如果你想支持属性的重构,类的改变,你至少需要一些代码生成器(如 InitializeComponenets 或 WinForms 的资源),但即使你能够做这样的事情,在某些指出您应该向该功能发出信号以重新生成这些东西,因此它永远不会是“自动”的。可能可以通过编写插件来实现类似的效果,但老实说,不知道这是否值得所有这些工作。可能有人会提供更聪明的解决方案
      猜你喜欢
      • 1970-01-01
      • 2019-06-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 2011-06-21
      • 1970-01-01
      相关资源
      最近更新 更多