Search code examples
c#castingdatagridviewcombobox

Casting a DataGridViewComboBoxColumn item into another object fails


This method is part of my derived class from DataGridViewComboBoxColumn:

public ComboboxColourItem InsertColour(ushort iColourIndex)
{
    ComboboxColourItem ocbItem = ComboboxColourItem.Create(iColourIndex);

    bool bAppend = true;
    if (Items.Count > 15)
    {
        // There are other colours, need to find right index
        for(int i = 15; i < Items.Count; i++)
        {
            //if(ocbItem.Index < (ComboboxColourItem)Items[i].Index)
            //{
            //}
            ComboboxColourItem ocbItem2 = (ComboboxColourItem)Items[i];
            if (ocbItem.Index < ocbItem2.Index)
            {
                bAppend = false;
                Items.Insert(i, ocbItem);
                break;
            }
        }
    }
    if (bAppend)
        Items.Add(ocbItem);

    return ocbItem;
}

The Items contain ComboboxColourItem objects. Here is the definition of those items:

public class ComboboxColourItem
{
    public string Name { get; set; }
    public ushort Index { get; set; }
    public Color Value { get; set; }

    public ComboboxColourItem(string Name, ushort Index, Color Value)
    {
        this.Name = Name;
        this.Index = Index;
        this.Value = Value;
    }
    public override string ToString()
    {
        return Name;
    }

    static public ComboboxColourItem Create(ushort iColourIndex)
    {
        OdCmColor oColour = new OdCmColor();

        oColour.setColorIndex(iColourIndex);

        CultureInfo cultureInfo = Thread.CurrentThread.CurrentCulture;
        TextInfo textInfo = cultureInfo.TextInfo;

        String strColour = textInfo.ToTitleCase(oColour.colorNameForDisplay());
        if (iColourIndex < 8)
            strColour = String.Format("{0} ({1})", strColour, iColourIndex);
        else if (iColourIndex == 8 || iColourIndex == 9 || iColourIndex >= 250)
            strColour = String.Format("Grey Shade ({0})", iColourIndex);
        else
            strColour = String.Format("Other ({0})", iColourIndex);
        ComboboxColourItem oColourItem = new ComboboxColourItem(
            strColour,
            iColourIndex,
            Color.FromArgb(oColour.red(), oColour.green(), oColour.blue()));

        oColour.Dispose();

        return oColourItem;
    }
}

I know that I can use foreach(ComboboxColourItem ocbItem2 in Items) but I need to start from a certain index. So I decided to use a regular for loop.

I thought that I could do this to cast the item from object:

if(ocbItem.Index < (ComboboxColourItem)Items[i].Index)
{
}

Does not like the cast. Yet, if I do this:

ComboboxColourItem ocbItem2 = (ComboboxColourItem)Items[i];
if (ocbItem.Index < ocbItem2.Index)
{
}

That works perfectly. So why could I not cast? Did I do it wrong? I don't think I can use foreach in this situation.


Solution

  • Since the member access has higher precedence than the cast (C# operator precedence), the following

    (ComboboxColourItem)Items[i].Index
    

    is equivalent to

    (ComboboxColourItem)(Items[i].Index)
    

    which of course is invalid.

    Use this instead

    ((ComboboxColourItem)Items[i]).Index