如何在静态方法中填充DataGridView?

问题描述 投票:0回答:2

我正在努力填补

DataGridView
。但是,由于我是在
FileSystemWatcher
处理程序(即 静态类)上执行此操作,因此它给了我错误:

An object reference is required for non-static field, method, or property

如果我将类更改为 non-static 那么

EventHandler
会给出相同的错误。我目前处于循环中,找不到解决方案。你能帮我解决这个问题吗?

    class FCheck
    {
        public static void tpCard_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId + " " + "File:" + e.FullPath);

            if (Path.GetExtension(e.FullPath) == ".f")
            {
// Do something....

                Form1.populateTable(tp);
            }

        }
    }

这是主表格1:

        public void checkTPFiles()
        {
            FileSystemWatcher fw = new FileSystemWatcher(@"F:\tmp");
            fw.Created += LSCheck.tpCard_Created;
            fw.EnableRaisingEvents = true;                                         
        }

        public static void populateTable(TpCard tpCard)
        {
            DataGridViewRow row = (DataGridViewRow)dataGridView1.Rows[0].Clone();
            row.Cells[1].Value = tpCard.FNumber;
            dataGridView1.Rows.Add(row);
        }
c# datagridview static static-methods
2个回答
0
投票

一个简单的解决方案是将

Form1
实例传递给您的
FCheck
类。

在您的表格1中:

    public void checkTPFiles()
    {
        FileSystemWatcher fw = new FileSystemWatcher(@"F:\tmp");

        var fCheck = new FCheck(this);       // <= passes Form1 instance
        fw.Created += fCheck.tpCard_Created; // <= no static call anymore
        fw.EnableRaisingEvents = true;
    }

    public void populateTable(TpCard tpCard)
    {

    }

在你的班级F检查

class FCheck
{
    private readonly Form1 _form;

    public FCheck(Form1 form) 
    {
        _form = form;  // <= remember Form1 instance for future use
    }

    public void tpCard_Created(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("ThreadId:" + Thread.CurrentThread.ManagedThreadId + " " + "File:" + e.FullPath);

        if (Path.GetExtension(e.FullPath) == ".f")
        {                
            // Do something....

            _form.populateTable(tp);  // <= now it is possible to call instance methods
        }

    }
}

这不是最好的解决方案,因为这些类是“紧密耦合”的。 使用事件和委托,以便

FCheck

引发事件并且

Form1
对其做出反应,将是更好的方法。上述解决方案是让您运行的第一步。
    


0
投票
Invoke(Delegate)

AND 跨线程操作无效:从创建该控件的线程以外的线程访问控制。 基于上面的两篇文章,我为DataGridView编写了这个扩展方法。它在尝试添加到网格列表之前检查 grid.InvokeRequired 。您还可以在此处包含代码来更新/删除列表中的对象。 (我使用的是此处的 SortableBindingList,但如果需要,您可以使用常规绑定列表:https://martinwilley.com/net/code/forms/sortablebindinglist.html

)。根据您的网格,您可能需要在 BindingList 中使用的任何类上使用 INotifyPropertyChanged 接口。

/// <summary> /// This is a static extension method for DataGridViews. /// It allows us to add an object to the bound Datasource (SortableBindingList) of the grids. /// </summary> public static class DataViewGridExtensions { private delegate void AddToGridListThreadSafeDelegate<T>( DataGridView grid, object modelObject); /// <summary> /// This method is based on the following: /// https://stackoverflow.com/questions/142003/cross-thread-operation-not-valid-control-accessed-from-a-thread-other-than-the /// https://stackoverflow.com/questions/661561/how-do-i-update-the-gui-from-another-thread /// This method does NOT modifying a single control's property value. /// This method will instead Add a T modelObject to a DataGridView's DataSource. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="grid"></param> /// <param name="modelObject"></param> public static void AddToGridList<T>(this DataGridView grid, T modelObject) { if (modelObject != null) { if (grid.InvokeRequired) { grid.BeginInvoke(new AddToGridListThreadSafeDelegate<T>(AddToGridList), new object[] { grid, modelObject }); } else { //Our SortableBindingList<T> uses BindingList as a base class. //We are using these lists as bound DataSources for our DataGridViews. //BindingSource implements IBindingList, so we can cast the grid's Datasource directly to BindingSource //and then use the Add method to add our modelObject to the grid. //This will cause the UI grid to be updated accordingly. BindingSource bs = (BindingSource)grid.DataSource; bs.Add(modelObject); } } } }


© www.soinside.com 2019 - 2024. All rights reserved.