C#刷新datagridview或listview中的websocket实时异步数据
首先,我要说的是,我是一名初学C#的程序员,有大约6个月的经验。我可能不会遵循最佳实践,但我渴望学习。:) 我正在构建一个小应用程序,显示我在交易所进行的所有订单和交易。此exchange提供了一个WebSocket服务器,我可以成功订阅该服务器。数据正在进入,我可以成功地将其排队并同步处理。在我的应用程序中,我有一个DataGridView,其绑定源链接到它。此DataGridView需要显示所有未结订单。当订单被填写时,它必须从列表中消失,当我打开一个新订单时,它应该显示在列表中。非常基本 这是我有生以来第一次使用MVP模式。更新标签很容易,但是管理DataGridView我发现有点复杂。我想知道什么是拥有总是最新的DataGridView的最佳方式 我的表格:C#刷新datagridview或listview中的websocket实时异步数据,c#,listview,asynchronous,websocket,datagridview,C#,Listview,Asynchronous,Websocket,Datagridview,首先,我要说的是,我是一名初学C#的程序员,有大约6个月的经验。我可能不会遵循最佳实践,但我渴望学习。:) 我正在构建一个小应用程序,显示我在交易所进行的所有订单和交易。此exchange提供了一个WebSocket服务器,我可以成功订阅该服务器。数据正在进入,我可以成功地将其排队并同步处理。在我的应用程序中,我有一个DataGridView,其绑定源链接到它。此DataGridView需要显示所有未结订单。当订单被填写时,它必须从列表中消失,当我打开一个新订单时,它应该显示在列表中。非常基本
public partial class MTMainForm : Form, IMTMainForm
{
public BindingSource bSRCOrders
{
get => (BindingSource)dGVOrders.DataSource;
set => SetBindingSRC(dGVOrders, value); //dGVOrders = DataGridView
}
private void SetBindingSRC(DataGridView dgv, BindingSource bs)
{
if (dgv.DataBindings.Equals(bs))
return;
if (!InvokeRequired)
{
dgv.DataSource = bs;
return;
}
this.Invoke(new Action(() =>
{
dgv.DataSource = bs;
}));
}
}
接口:
interface IMTMainForm
{
BindingSource bSRCOrders { get; set; }
}
我有一个演示者课程:
class MTMainPresenter
{
private readonly IMTMainForm _view;
private void Subscribe(WebsocketClient wsc)
{
client.Streams.OrderStream
.Select(ordr =>
Observable.FromAsync(async () => {
HandleOrderResponse(ordr);
}))
.Concat() //All incoming orders are queued and that is the way I want it.
.Subscribe();
}
private void HandleOrderResponse(OrderResponse response)
{
switch (response.Action)
{
case ExchAction.Insert:
??
break;
case ExchAction.Delete:
??
break;
case ExchAction.Update:
??
break;
}
}
}
我需要的是一些在DataGridView中插入、删除和搜索/更新数据的建议,以便我的列表始终表示我在exchange上的订单状态
提前感谢你的帮助。
保罗(我明白了!)
我的表格:
public partial class MTMainForm : Form, IMTMainForm
{
public BindingSource bSRCOrders
{
get => (BindingSource)dGVOrders.DataSource;
set => SetBindingSRC(dGVOrders, value); //dGVOrders = DataGridView
}
private void SetBindingSRC(DataGridView dgv, BindingSource bs)
{
//if (dgv.DataBindings.Equals(bs)) --> Commented this
// return; --> Commented this
if (!InvokeRequired)
{
dgv.DataSource = bs;
((BindingSource)dgv.DataSource).ResetBindings(false); // Add this to refresh DGV
return;
}
this.Invoke(new Action(() =>
{
dgv.DataSource = bs;
((BindingSource)dgv.DataSource).ResetBindings(false); // Add this to refresh DGV
}));
}
}
我还添加了一个计时器,用于刷新绑定源。我还得检查一下这是否仍然有必要
我用维护的列表创建了一个新类。我还添加了一个方法,将列表转换为BindingSource,用于替换现有的BindingSource
class OrdersStatsHandler
{
private readonly List<Order> _orderList = new List<Order>();
public void HandleOrder(Order newOrder)
{
List<string> removeList = new List<string>() { newOrder.OrderId };
switch (newOrder.OrdStatus)
{
case OrderStatus.Rejected:
case OrderStatus.Filled:
case OrderStatus.Canceled:
_orderList.RemoveAll(r => removeList.Any(a => a == r.OrderId));
break;
case OrderStatus.New:
case OrderStatus.PartiallyFilled:
if (_orderList.Where(o => o.OrderId == newOrder.OrderId).Count() == 0)
_orderList.Add(newOrder);
else
{
_orderList.RemoveAll(r => removeList.Any(a => a == r.OrderId));
_orderList.Add(newOrder);
}
break;
}
}
public BindingSource GetBindingSource()
{
BindingSource bs = new BindingSource();
bs.DataSource = _orderList;
return bs;
}
}
不客气!:)
class MTMainPresenter
{
private readonly IMTMainForm _view;
private OrdersStatsHandler _orderStatsHandler;
private void Subscribe(WebsocketClient wsc)
{
client.Streams.OrderStream
.Select(ordr =>
Observable.FromAsync(async () => {
HandleOrderResponse(ordr);
}))
.Concat() //All incoming orders are queued and that is the way I want it.
.Subscribe();
}
private void HandleOrderResponse(OrderResponse response)
{
try
{
foreach (Order o in response.Data)
{
_orderStatsHandler.HandleOrder(o);
}
var bs = _orderStatsHandler.GetBindingSource();
_view.bSRCOrders = bs;
}
catch (Exception exc)
{
Log.Error(exc.Message);
}
}
}