문제

EDIT: I'm a dummy

So... it turns out that the problem is in the following line;

item.UseItemStyleForSubItems = false;

I had copied this line from another piece of code where I was just trying to change one SubItem, then I changed my mind and decided that here I wanted to change the whole row. My listView has a couple of hidden columns, and when UseItemStyleForSubItems is set to false, it only changes the first SubItem. So the change was probably happening the whole time, just not across the entire row.

Here's what grayOut looks like now:

    internal static void grayOut(ref ListView myLV)
    {
        //change each selected item to gray text
        //currently, multiselect is turned off, so this will only be one item at a time
        foreach (ListViewItem item in myLV.SelectedItems)
        {
            item.Selected = false;
            item.ForeColor = Color.Gray;
            item.BackColor = Color.Gainsboro;
            item.Font = new Font("MS Sans Serif", 8, FontStyle.Italic);
        }
    }

It was as easy as I thought it should be. :)

Original Question

I'm using the following code to change the ForeColor of items for which a selected action has already been performed.

     public partial claass MyForm: Form
     private void bgProgress_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
         Global.grayOut(ref this.lvUsers);
    }

    ...

    public static class Global

    internal static void grayOut(ref ListView myLV)
    {
        //change each selected item to gray text
        //currently, multiselect is turned off, so this will only be one item at a time
        foreach (ListViewItem item in myLV.SelectedItems)
        {
            item.UseItemStyleForSubItems = false;
            item.ForeColor = Color.Gray;
            item.Font = new Font("MS Sans Serif", 10, FontStyle.Italic);
            item.Selected = false;
        }

        myLV.Refresh();
    }

I have two problems.

  1. The property changes, but that change does not display. In other words, I know that the ForeColor is changed to gray, because later I check to see if it is gray when the user tries to perform a certain action. However, it doesn't appear gray or italicized.
  2. I'm also using the following to try and cancel a MouseDown event to keep the item from being selected again, but it still ends up being selected:

    private void lvUsers_MouseDown(object sender, MouseEventArgs e)
    {
        // Make sure it was a single left click, like the normal Click event
        if (e.Button == MouseButtons.Left)
        {
            ListViewHitTestInfo htInfo = lvUsers.HitTest(e.X, e.Y);
            if (htInfo.Item.ForeColor == Color.Gray)
            {
                return;
            }
        }
    }
    

I haven't found any other method for cancelling a MouseDown event, so I'm not sure what else to try.

도움이 되었습니까?

해결책

You can get what you are after by relying on the method associated with the SelectedIndexChanged Event. Sample code:

private void myLV_SelectedIndexChanged(object sender, EventArgs e)
{
    if (myLV.SelectedItems.Count > 0)
    {
        foreach (ListViewItem item in myLV.SelectedItems)
        {
            if (item.ForeColor == Color.Gray)
            {
                item.Selected = false;
            }
            else
            {
                ListViewItem tempItem = item;
                grayOut2(ref tempItem);
            }
        }
    }
}

This code grays out any item you select if it hasn't been selected before (not grayed out); otherwise, it avoids it to be selected. GrayOut2 is a version of your function only taking into consideration the given item.

internal static void grayOut2(ref ListViewItem item)
{
    //change each selected item to gray text
    //currently, multiselect is turned off, so this will only be one item at a time
    item.UseItemStyleForSubItems = false;
    item.ForeColor = Color.Gray;
    item.Font = new Font("MS Sans Serif", 10, FontStyle.Italic);
    item.Selected = false;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top