C# 交互式代理API数据表覆盖行
我正在使用InteractiveBrokersCAPI并试图从AccountSummary对象创建一个Datatable,但表中的行被覆盖,只显示最后一个值 我不知道发生了什么事。我认为可能是属性类型与列名匹配,因此在同一行的顶部写得太多 预期产量 这是调用ConvertToDataTable方法的方法C# 交互式代理API数据表覆盖行,c#,datatable,interactive-brokers,C#,Datatable,Interactive Brokers,我正在使用InteractiveBrokersCAPI并试图从AccountSummary对象创建一个Datatable,但表中的行被覆盖,只显示最后一个值 我不知道发生了什么事。我认为可能是属性类型与列名匹配,因此在同一行的顶部写得太多 预期产量 这是调用ConvertToDataTable方法的方法 public void UpdateUI(IBMessage message) { switch (message.Type) {
public void UpdateUI(IBMessage message)
{
switch (message.Type)
{
case MessageType.AccountSummary:
ConverToDataTable((AccountSummaryMessage)message);
break;
case MessageType.AccountSummaryEnd:
HandleAccountSummaryEnd();
break;
case MessageType.AccountValue:
HandleAccountValue((AccountValueMessage)message);
break;
case MessageType.PortfolioValue:
HandlePortfolioValue((UpdatePortfolioMessage)message);
break;
case MessageType.AccountDownloadEnd:
break;
case MessageType.Position:
HandlePosition((PositionMessage)message);
break;
case MessageType.PositionEnd:
break;
}
}
这就是我试图从中构建数据表的对象
public class AccountSummaryMessage : IBMessage
{
private int requestId;
private string account;
private string tag;
private string value;
private string currency;
public int RequestId
{
get { return requestId; }
set { requestId = value; }
}
public string Account
{
get { return account; }
set { account = value; }
}
public string Tag
{
get { return tag; }
set { tag = value; }
}
public string Value
{
get { return this.value; }
set { this.value = value; }
}
public string Currency
{
get { return currency; }
set { currency = value; }
}
public AccountSummaryMessage(int requestId, string account, string tag, string value, string currency)
{
Type = MessageType.AccountSummary;
RequestId = requestId;
Account = account;
Tag = tag;
Value = value;
Currency = currency;
}
}
在添加行之前,应该首先循环并将列添加到表中。如果您只是试图在ConvertODatable函数中创建一个包含单行的表,则需要将其更改为类似以下内容:
public static DataTable ConverToDataTable(object obj)
{
DataTable dt = new DataTable();
var dataType = obj.GetType();
dataType.GetProperties().ToList().ForEach(f =>
{
try
{
dt.Columns.Add(f.Name, f.PropertyType);
}
catch
{
}
});
DataRow newRow = dt.NewRow();
foreach (var prop in dataType.GetProperties())
{
newRow[prop.Name] = prop.GetValue(obj);
}
dt.Rows.Add(newRow);
return dt;
}
编辑:如我在下面的评论中所解释的,要添加多行,您有几个选项。以下是两种可能的方法:
在类中使用私有表变量在需要时继续追加行:
使用可枚举类型一次添加所有行:
了解可枚举类型可能会有所帮助。这是一个很好的开始。我使用了Kevin的第一个编辑,它工作得非常完美。您从哪里调用ConvertODatable?您是在列表上循环还是在AccountSummaryMessage对象的多个实例上以任何方式调用该函数?嗨,Kevin/jstreet,感谢您花时间回答。我添加了调用ConvertToDataable方法的方法。我仍然无法理解将在何处追加多行。每次调用ConvertToDataTable时,您都在创建一个包含一行的新数据表。嗨,Kevin,谢谢您的帮助。我添加了一张我正在努力实现的图片。我正在尝试显示多行。当我使用datagridview时,我可以获得预期的输出,但当尝试使用datatable时,我无法获得正确的输出。是否在函数中指定ConvertDataTable的返回值?或者传递obj参数的可枚举类型?我看不到任何其他使用该函数添加多行的方法。不,这两种方法都没有。我以前从未使用过可枚举类型。我认为您有两种选择:1。您可以将DataTable保留为私有/公共变量,并将函数更改为附加返回的DataTable,或将函数更改为非静态void并修改DataTable变量。2.您可以向函数传递一个可枚举项,并一次追加所有行。我会更新我的答案给你们看。非常感谢Kevin,这很有效,也阅读了IEnumerables,很有趣地看到了a for each在幕后是如何工作的。
public static DataTable ConverToDataTable(object obj)
{
DataTable dt = new DataTable();
var dataType = obj.GetType();
dataType.GetProperties().ToList().ForEach(f =>
{
try
{
dt.Columns.Add(f.Name, f.PropertyType);
}
catch
{
}
});
DataRow newRow = dt.NewRow();
foreach (var prop in dataType.GetProperties())
{
newRow[prop.Name] = prop.GetValue(obj);
}
dt.Rows.Add(newRow);
return dt;
}
private DataDate table = null;
public void ConverToDataTable(object obj)
{
var dataType = obj.GetType();
if (table == null)
{
table = new DataTable();
dataType.GetProperties().ToList().ForEach(f =>
{
table.Columns.Add(f.Name, f.PropertyType);
});
}
DataRow newRow = table.NewRow();
foreach (var prop in dataType.GetProperties())
{
newRow[prop.Name] = prop.GetValue(obj);
}
table.Rows.Add(newRow);
}
public static DataTable ConverToDataTable(IEnumerable<object> obj)
{
DataTable dt = new DataTable();
var dataType = obj.First().GetType();
dataType.GetProperties().ToList().ForEach(f =>
{
try
{
dt.Columns.Add(f.Name, f.PropertyType);
}
catch
{
}
});
foreach (var item in obj)
{
DataRow newRow = dt.NewRow();
foreach (var prop in dataType.GetProperties())
{
newRow[prop.Name] = prop.GetValue(item);
}
dt.Rows.Add(newRow);
}
return dt;
}