2

我正在创建一个小型 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

4

4 回答 4

3

当您将 List 绑定到 DataGridView 并修改原始 List 时,DataGridView 不会自动更新其显示。它只会显示绑定时列表中存在的数据。

如果希望 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)。

于 2012-07-09T23:20:42.790 回答
3

您可以将 替换List<Message>()为自定义类并继承BindingList<T>并附Message Dispatcher加到其中。例子

public class MessageList : BindingList<Message>
{
}

在您的主要表单中订阅该ListChanged事件,您就可以开始了。

于 2012-07-10T03:39:27.537 回答
1

当我像这样使用 datagridview 做任何事情时,我使用以下系统:-

我有一个 DataObject,在你的情况下是一个 List 对象。然后我创建一个绑定对象并将其数据源设置为 DataObject。我将 DatagridView 数据源设置为绑定对象。

这样,当您对数据对象进行更改时,它们会自动过滤到数据网格。

在您的情况下,您应该按照 Turbot 所说的那样,创建一个继承 BindingList 对象的类,然后您就可以开始了。

于 2012-07-10T08:11:06.840 回答
0

尝试使用 aBindingList而不是List. 它形成双向连接。(它在 ComponentModel 命名空间中)

于 2012-07-09T23:11:35.730 回答