【问题标题】:Bind a linkedlist to a datagridview将链表绑定到数据网格视图
【发布时间】:2016-10-23 23:29:19
【问题描述】:

我正在尝试将链表绑定到数据网格视图。下面的方法适用于除数组之外的类中的属性。 如果我将数组声明为新实例,则正确创建了链表,但数组未绑定到 datagridview。 如果将数组创建为属性(我认为代码是正确的)在创建linkedlist时会导致An unhandled exception of type 'System.StackOverflowException' occurred

感谢您的帮助。

    public class PayoffNode
                {
                    public int DealNo { get; set; }
                    public string Category { get; set; }
                    public string Strategy { get; set; }
                    public string GreekType { get; set; }
                    // declare array as instance or as a property?
                    //public double[] Data = new double[22];  
                    public double[] Data
                    {
                        get { return Data; }
                        set { Data = value; }
                    }
                }

    LinkedList<Globals.PayoffNode> PayLL = new LinkedList<Globals.PayoffNode>();
                Random Rnd = new Random();
                for (int K = 1; K <= 10; K++)
                {
                    var T = new Globals.PayoffNode();
                    T.Category = "Account==" + K;
                    T.GreekType = "Greek==" + K;
                    T.DealNo = K;
                    T.Strategy = "Strategy==" + K;
                    for (int DP = 1; DP <= 21; DP++)
                    {
                        T.Data[DP] = Rnd.Next(10, 99);
                    }
                    PayLL.AddLast(T);
                }

                List<Globals.PayoffNode> qP = (from P in PayLL
                                               where P.Category == "Account==4" && P.DealNo == 4 && P.GreekType == "Greek==4" && P.Strategy == "Strategy==4"
                                               select P).ToList();

     PayoffTable.DataSource = qP;

更新: 感谢 cmets,这似乎有效。

public class PayoffNode
            {
                public int DealNo { get; set; }
                public string Category { get; set; }
                public string Strategy { get; set; }
                public string GreekType { get; set; }
                public double Data1 { get; set; }
                public double Data2 { get; set; }
                public double Data3 { get; set; }
                public double[] Data = new double[22];
            }

LinkedList<Globals.PayoffNode> PayLL = new LinkedList<Globals.PayoffNode>();
            Random Rnd = new Random();
            for (int K = 1; K <= 10; K++)
            {
                var T = new Globals.PayoffNode();
                T.Category = "Account==" + K;
                T.GreekType = "Greek==" + K;
                T.DealNo = K;
                T.Strategy = "Strategy==" + K;
                for (int DP = 1; DP <= 21; DP++)
                {
                    T.Data[DP] = Rnd.Next(10, 99);
                }
                PayLL.AddLast(T);
            }

List<Globals.PayoffNode> qP = (from P in PayLL
                                           where P.Category == "Account==4" && P.DealNo == 4 && P.GreekType == "Greek==4" && P.Strategy == "Strategy==4"
                                           select new Globals.PayoffNode()
                                           {
                                               Category=P.Category,
                                               DealNo=P.DealNo,
                                               GreekType=P.GreekType,
                                               Strategy=P.Strategy,
                                               Data1=P.Data[1],
                                               Data2 = P.Data[2],
                                               Data3 = P.Data[3],
                                           }).ToList();

PayoffTable.DataSource = qP;

【问题讨论】:

  • return Data; 这会导致无限递归。
  • 如果将数组绑定到 datagridview 列会发生什么?
  • 我希望看到 datagridview 中的每条记录看起来像:Category-GreekType-DealNo-Strategy-Data[1]-Data[2]... 所以所有变量,然后是数组
  • 我希望它这么简单,但不幸的是每个公共属性只绑定到一列,因此您需要为每一列单独的 Data1、Data2 等属性。
  • 是的,你是对的,我对查询的期望太高了。请看看我的更新,看看你能不能让它更有效率?

标签: c# data-binding datagridview linked-list


【解决方案1】:

避免制作 21 个 Data 属性的一种方法是将 List 转换为 DataTable:

class PayoffNode
{
    public int DealNo;
    public string Category;
    public double[] Data; // = new double[21];
}

然后

Random Rnd = new Random();

List<PayoffNode> PayLL = Enumerable.Range(1, 10).Select(i => new PayoffNode {
    DealNo = i,
    Category = "Account==" + i,
    Data = Enumerable.Range(1, 21).Select(d => (double)Rnd.Next(10, 99)).ToArray()
}).ToList();

// List<PayoffNode> to DataTable
var dt = new DataTable();
dt.Columns.Add("DealNo", typeof(int));
dt.Columns.Add("Category"); // typeof(string) by default
for (int i = 1; i <= 21; i++)
    dt.Columns.Add("Data" + i, typeof(double));

foreach (var P in PayLL)
{
    var dr = dt.Rows.Add(P.DealNo, P.Category);
    for (int i = 0; i < 21; i++)
        dr[i+2] = P.Data[i]; // +2 is the number of fields before the Data fields
}

PayoffTable.DataSource = dt;
dt.DefaultView.RowFilter = " Category = 'Account==4' ";

优点是您只需设置一次DataSource,只需更改RowFilter 即可对其进行过滤。此外,在DataGridView 中所做的任何更改都会更改DataTable,反之亦然。

请注意,C# 和大多数其他语言中的数组从 0 开始而不是从 1(.Data[0] 访问数组中的第一项),因此在我的示例中访问 Data 数组的 for 循环是从 0 到 20 .

【讨论】:

  • 谢谢,这看起来更有效率。我只是更喜欢使用 base 1 数组。
【解决方案2】:
public double[] Data
{
    get { return Data; }
    set { Data = value; }
}

这就是问题所在,set 和 get 方法中的对象需要引用不同的对象,否则无论何时设置或尝试检索对象值,它都会无限地调用这些方法。应该是……

private double[] _data;
public double[] Data
{
    get { return _data; }
    set { _data = value; }
}

或者...

public double[] Data { get; set; }

【讨论】:

  • 我同意,但您的回答无效。我在T.Data[DP] = Rnd.Next(10, 99);Object reference not set to an instance of an object. 时遇到错误
猜你喜欢
  • 2011-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多