【问题标题】:DataGridView not updating in UI when underlying datasource changes底层数据源更改时,DataGridView 不会在 UI 中更新
【发布时间】:2012-07-10 16:11:06
【问题描述】:

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

【问题讨论】:

  • 您是否尝试将列表设置为 BindingSource,并将 BindingSource 设置为网格的源。 BindingSource 使事物保持同步

标签: c# winforms


【解决方案1】:

您可以将List&lt;Message&gt;() 替换为自定义类并继承BindingList&lt;T&gt; 并将Message Dispatcher 附加到其中。 示例

public class MessageList : BindingList<Message>
{
}

在你的主要形式 订阅ListChanged 活动,一切顺利。

【讨论】:

    【解决方案2】:

    当你绑定一个List然后修改原始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)的集合。

    【讨论】:

      【解决方案3】:

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

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

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

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-05-27
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-11-29
          • 1970-01-01
          相关资源
          最近更新 更多