我正在创建一个小的Windows窗体应用程序,它将从后台线程接收消息,然后将它们添加到主窗体上的列表中。在表单上,我有一个 DataGridView , DataSource 设置为邮件列表(例如List<Message>
)
目前,消息堆积如山,但我无法通过 DataGridView 来呈现消息。以下是我使用的方法的摘要。
1。初始化主窗体设置绑定并启动消息例程
internal Main(IMessageDispatcher messageDispatcher, IMessagePublisher messagePublisher)
{
InitializeComponent();
_messageEntries = new List<Message>();
BindToMessageEntriesList();
_messageDispatcher = messageDispatcher;
_messageDispatcher.OnMessageReceived += MessageDispatcher_OnMessageReceived;
_messageDispatcher.Start();
}
private void BindToMessageEntriesList()
{
MessageEntriesGrid.DataSource = _messageEntries;
}
2. 处理收到的消息并添加到内部列表
private void MessageDispatcher_OnMessageReceived(Message message)
{
lock (_logEntries)
{
_messageEntries.Add(message);
}
var cb = new RefreshListCallbackDelegate(RefreshView);
this.Invoke(cb);
}
3. 在主线程上刷新
private void RefreshView()
{
MessageEntriesGrid.Refresh();
}
任何人都可以建议我如何让UI反映出现的变化。
注意:我也尝试过使用Invalidate方法和ResetBindings方法。我还尝试将列表切换为ObservableCollection
答案 0 :(得分:3)
将List绑定到DataGridView时,DataGridView不会自动更新其显示,然后修改原始List。它只会在您绑定时显示列表中存在的数据。
如果希望DataGridView在绑定集合更改时动态更新,则需要绑定实现IBindingList的集合(如BindingList http://msdn.microsoft.com/en-us/library/ms132679(v=vs.90).aspx)或IBindingListView(如BindingSource http://msdn.microsoft.com/en-us/library/system.windows.forms.bindingsource(v=vs.90).aspx)。
答案 1 :(得分:3)
您可以将List<Message>()
替换为自定义类并继承BindingList<T>
并将Message Dispatcher
附加到其中。
实施例
public class MessageList : BindingList<Message>
{
}
在您的主要表单中
在ListChanged
事件中加入,你很高兴。
答案 2 :(得分:1)
当我使用datagridview做任何事情时,我使用以下系统: -
我有一个DataObject,在你的情况下是一个List对象。 然后我创建一个Binding对象并将其数据源设置为DataObject。 我将DatagridView DataSource设置为绑定对象。
这样,当您对数据对象进行更改时,它们会自动过滤到数据网格。
在你的情况下,你应该像Turbot一样说,创建一个继承BindingList对象的类,你就可以了。
答案 3 :(得分:0)
尝试使用BindingList
代替List
。它形成双向连接。 (它位于ComponentModel名称空间中)