简体   繁体   中英

How do I resize Listview columns in a threadsafe manner - C#

I have a query to a database on a seperate thread and on the return I invoke a threadsafe call. But an exception is created - what am I doing wrong?

Note I also populate the list view but have left it out for clarity

 private void ThreadSafeListView()
    {


        if (this.listView1.InvokeRequired)
        {
            try
            {
                ThreadSafe Operation d = new ThreadSafeOperation(ThreadSafeListView);
                this.Invoke(d );
            }
            catch { }
        }
        else
        {


            listView1.Columns[0].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            listView1.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            listView1.Columns[2].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
            listView1.Columns[3].AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);
            listView1.Columns[4].AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);


        }
    }

Exception Details= InvalidOperationException : "Cross-thread operation not valid: Control 'listView1' accessed from a thread other than the thread it was created on."

What exception is thrown? If it's still a thread-safe exception, then it may be because you're not invoking from the item that requires invocation. Try:

listView1.Invoke(d)

rather than

this.Invoke(d)

In theory this is the form, so it should work, but without more information about the exception this is my only guess.

//Here ilv is the List, who's column are to be resized
//Get the current column widths
ArrayList widths = new ArrayList();
foreach (ColumnHeader ch in ilv.Columns)
{
    widths.Add(ch.Width);
}

//Get the total width of all the columns
int total_width = 0;
for (int i = 0; i < widths.Count; i++)
{
     total_width += (int)widths[i];
}

//Calculate percentages and resize the columns.
for (int i = 0; i < widths.Count; i++)
{
    double c_width = (int)widths[i];
    double pect = (c_width / total_width);

    //get the new width, leave out 25 pixels for scrollbar
    double n_width = (ilv.Width - 25) * pect;
    n_width = Math.Round(n_width, 0);

    //MessageBox.Show(c_width + " - " + pect + " - " + n_width);
    ilv.Columns[i].Width = (int)n_width;                    
}

I give up...I'm just spinning my wheels so instead I...

void listView1_Resize(object sender, EventArgs e)
    {
        listView1.Columns[0].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
        listView1.Columns[1].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
        listView1.Columns[2].AutoResize(ColumnHeaderAutoResizeStyle.ColumnContent);
        listView1.Columns[3].AutoResize(ColumnHeaderAutoResizeStyle.HeaderSize);

    }

you can do this:

private void listViewEx_ColumnWidthChanging(object sender, ColumnWidthChangingEventArgs e)
{
    e.Cancel = true;
    e.NewWidth = 60;
}

you can do the following code...

first get the value of listview onload..

then store it in a variable the do this code in the ColumnWidthChanging event property like this...

     e.cancel = true;
     e.NewWidth = // the declared variable in which you store the list view with value in the onload function of the form

Example is like this

    int a = 100;
    e.cancel =true;
    e.e.NewWidth = a;

just like that

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM