【问题标题】:Fill DataGridView on FbRemoteEvent在 FbRemoteEvent 上填充 DataGridView
【发布时间】:2014-05-22 19:42:54
【问题描述】:

我有一个 MainForm(带有 dataGridView)和 DataModule 类,带有我自己的 LoadDataTable 方法,它们执行 FbCommand 选择 sql 并在数据集中填充数据表和 FbRemoteEvent 捕获方法。当我运行我的应用程序时,在 MainForm_OnLoad 我调用 LoadDataTable 方法并且我的 dataGridView 成功显示数据。但是当我的应用程序从服务器捕获 FbRemoteEvent 并调用 LoadDataTable 方法时,dataGridView 中发生了异常。为什么?

主窗体:

public partial class MainForm : Form
{
    private readonly DataModule _dataModule = DataModule.GetInstance();

    public MainForm()
    {
        InitializeComponent();
    }

    private void MainForm_Load(object sender, EventArgs e)
    {
        dataGridView1.AutoGenerateColumns = false;
        dataGridView1.DataSource = _dataModule.AppDataSet;
        dataGridView1.DataMember = "MESSAGEQUEUE";
        _dataModule.LoadMessageQueueDataTable();
    }
}

数据模块:

    private void FirebirdRemoteEventOnRemoteEventCounts(object sender, FbRemoteEventEventArgs fbRemoteEventEventArgs)
        {
            switch (fbRemoteEventEventArgs.Name.Trim().ToUpper())
            {
                case "QUEUE_NEW_MESSAGE":
                    if (fbRemoteEventEventArgs.Counts > 0)
                    {
                        LoadMessageQueueDataTable();
                    }
                    break;
            }
        }

public void LoadMessageQueueDataTable()
        {
            if (ConnectToFirebird())
            {
                using (var firebirdTransaction = FirebirdConnection.BeginTransaction())
                {
                    using (var firebirdCommand = new FbCommand
                    {
                        Connection = firebirdTransaction.Connection,
                        Transaction = firebirdTransaction,
                        CommandType = CommandType.Text,
                        CommandText = "select MESSAGEQUEUEID, CREATEDATETIME, SENDER, RECIPIENT, TEXT from MESSAGEQUEUE"
                    })
                    {
                        AppDataSet.Tables["MESSAGEQUEUE"].Clear();
                        try
                        {
                            AppDataSet.Tables["MESSAGEQUEUE"].Load(firebirdCommand.ExecuteReader());
                            firebirdCommand.Transaction.Commit();
                        }
                        catch (FbException firebirdException)
                        {
                            firebirdCommand.Transaction.Rollback();
                        }
                    }
                }
            }
        }

错误:

【问题讨论】:

  • 能否改为显示英文错误消息。另外,您是在事件线程还是在其他线程上填充数据集?
  • @MarkRotteveel DataGridView 中的异常:System.IndexOutOfRangeException:未设置索引 0。在 System.Windows.Forms.CurrencyManager.get_Item(Int32 index) 在 System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32 rowIndex) 要替换此默认窗口处理 DataError 事件。
  • @MarkRotteveel 捕获 FbRemoteEvent 时我没有创建另一个线程来加载数据表
  • 据我所知,Firebird 事件是在不同的线程上处理的(虽然不是 100% 确定)
  • @MarkRotteveel 如果我们直接在可视化组件中更新数据,我认为我们可以使用委托。但是数据集不是可视组件,也没有 InvokeRequired 属性......最奇怪的是一个类似的程序在成功的工作中,但我在这部分找不到项目之间的差异。

标签: c# winforms visual-studio datagridview firebird


【解决方案1】:

在 DataModule 类中添加和更改 FbRemoteEvent 处理程序:

public delegate void DelegateMessageQueueTableUpdate();
public event DelegateMessageQueueTableUpdate MessageQueueTableUpdate;

private void FirebirdRemoteEventOnRemoteEventCounts(object sender, FbRemoteEventEventArgs fbRemoteEventEventArgs)
        {
            switch (fbRemoteEventEventArgs.Name.Trim().ToUpper())
            {
                case "QUEUE_NEW_MESSAGE":
                    if (fbRemoteEventEventArgs.Counts > 0)
                    {
                        if (MessageQueueTableUpdate != null)
                        {
                            MessageQueueTableUpdate();
                        }
                    }
                    break;
            }
        }

在主窗体中:

public partial class MainForm : Form
    {
        private readonly DataModule _dataModule = DataModule.GetInstance();

        private delegate void RefreshMessageQueueTable();

        public MainForm()
        {
            InitializeComponent();
            _dataModule.MessageQueueTableUpdate += () =>
            {
                if (dataGridView1.InvokeRequired)
                {
                    dataGridView1.Invoke(new RefreshMessageQueueTable(_dataModule.LoadMessageQueueDataTable));
                }
                else
                {
                    _dataModule.LoadMessageQueueDataTable();
                }
            };
        }

        private void MainForm_Load(object sender, EventArgs e)
        {
            dataGridView1.DataSource = _dataModule.AppDataSet;
            dataGridView1.DataMember = "MESSAGEQUEUE";
            _dataModule.LoadMessageQueueDataTable();
        }
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-01-24
    • 2019-11-02
    • 1970-01-01
    • 2014-09-17
    • 2013-08-11
    • 2015-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多