Home > Net >  C# ListView.Invoke and ListView.FindItemWithText Error
C# ListView.Invoke and ListView.FindItemWithText Error

Time:05-06

So I am using C# and Forms, I have ListView with Items and I am trying to find Item with text.

I have seperate threads in 2 seperate scripts/classes (1. MainForm.cs and 2. workWithLists.cs I need to use FindItemWithText in workWithLists.cs) so I need to use invoke:

ListViewItem v = listView1.Invoke(listView1.FindItemWithText("TestName"));

But I have error when I use Invoke with FindItemWithText:

Cannot convert from "System.Windows.Forms.ListViewItem" to "System.Delegate"

Without Invoke:

ListViewItem v = listView1.FindItemWithText("TestName");

I don't have any Errors, But when I run the code it gives me Error:

Invalid multi-thread operation: An attempt was made to access control 'listView1' from a thread other than the thread it was created on.

Please somebody explain to me what am I doing wrong, And how to fix this.

Calling FindItemWithText from the thread listview1 was made is not an Answer : D

Edit: I have this code in MainForm.cs:

public static ListView list;
public delegate void FindInListViewDelegate(string name);
public FindInListViewDelegate FindInListView = new FindInListViewDelegate(Find);
        

public ListViewItem Find(string name)
{
     ListViewItem item = list.FindItemWithText(name);
     return item;
}

But I am getting Error: A field initializer cannot reference the non-static field, method, or property 'MainForm.Find(string)'

I was changing:

public ListViewItem Find(string name) {}

To:

public static ListViewItem Find(string name) {}

But then it gives another Error: 'ListViewItem MainForm.Find(string)' has the wrong return type

CodePudding user response:

Control.Invoke method, executes a delegate on the thread that owns the control's underlying window handle.

And listView1.FindItemWithText is not a delegate, so in your main thread declare an Action or a delegate and use it in your second thread.

Main thread:

public delegate void FindInListViewDelegate(string name);

public FindInListViewDelegate FindInListView = new FindInListViewDelegate(Find);

public ListViewItem Find(string name)
{
    var item = listView1.FindItemWitdhText(name);
    ...
}

Secondary thread:

myForm.Invoke(myForm.FindInListView, new object[] { nameToSearch });

You can use an Action too, I set up a small Console application:

internal class Program
{
    static public Action<string> FindInListView = (name) =>
    {
        Console.WriteLine($"Finding item {name} in ListView");
    };

    static async Task Main(string[] args)
    {
        await new TaskFactory().StartNew(() => { FindInListView.Invoke("Joan"); });
        return;
    }

}
  • Related