Matthias R.
Matthias R.

Reputation: 451

Datagridview: how to "typeconvert" a property from a list

I'm currently trying to fill a common datagridview, as I'm struggling with typeconverting. Here's my scenario:

I have an entity that has a custom enum:

public class HistoryItem
{
    public virtual int Id { get; set; }

    [TypeConverter(typeof(CommunicationTypeConverter))]
    public virtual CommunicationType TypeOfCommunication { get; set; }

    public virtual DateTime Date { get; set; }
    public virtual string Remark { get; set; }
}

public enum CommunicationType
{
    OutgoingCall,
    OutgoingEmail
}

As you can see I already marked the TypeOfCommunication property for typeconverting:

public class CommunicationTypeConverter : TypeConverter
{
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value is CommunicationType)
        {
            switch((CommunicationType)value)
            {
                case CommunicationType.OutgoingEmail:
                    return "OUTGOING_EMAIL";
            }
        }
        return base.ConvertFrom(context, culture, value);
    }
}

Currently I'm trying to convert the CommunicationType.ToString() string with a custom string.

I already had a read on this and I know the concept of typeconverting basically (from WPF), but I dont get the link when it comes to bind a list of this history items to my datagridview:

IList<HistoryItem> history = _currentCustomer.HistoryItems;
dgvCustomerHistory.DataSource = history;
dgvCustomerHistory.Columns.Add("TypeOfCommunication", "Type");
dgvCustomerHistory.Refresh();

My goal is to "replace" the CommunicationType strings with images/icon - just to let you know where I want to go with this.

Upvotes: 1

Views: 1342

Answers (1)

Moop
Moop

Reputation: 3601

To start, do you want to auto generate the columns in the DataGridView? If so, code it like:

IList<HistoryItem> history = _currentCustomer.HistoryItems;
dgvCustomerHistory.AutoGenerateColumns = true;
dgvCustomerHistory.DataSource = history;  

if not, do it like:

IList<HistoryItem> history = _currentCustomer.HistoryItems;
dgvCustomerHistory.AutoGenerateColumns = false;

DataGridViewTextBoxColumn column = new DataGridViewTextBoxColumn();
column.HeaderText = "Communication Type";
column.DataPropertyName = "TypeOfCommunication"; // Name of property
dgvCustomerHistory.Columns.Add(column);

dgvCustomerHistory.DataSource = history;  

I think you just need to add some more overrides to the CommunicationTypeConverter. You only were handling the ConvertFrom method, you need to handle the ConvertTo method and the CanConvert methods.

    public class CommunicationTypeConverter : TypeConverter
    {
        public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
        {
            return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
        }

        public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
        {
            return destinationType == typeof(string) || base.CanConvertTo(context, destinationType);
        }

        public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
        {
            if (value is string)
            {
                switch ((string)value)
                {
                    case "OUTGOING_EMAIL":
                        return CommunicationType.OutgoingEmail;
                    default:
                        return CommunicationType.OutgoingCall;
                }
            }
            return base.ConvertFrom(context, culture, value);
        }

        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
            if (destinationType == typeof(string))
            {
                if (value is CommunicationType)
                {
                    switch ((CommunicationType)value)
                    {
                        case CommunicationType.OutgoingEmail:
                            return "OUTGOING_EMAIL";
                        default:
                            return "OUTGOING_CALL";
                    }
                }
            }
            return base.ConvertTo(context, culture, value, destinationType);
        }
    }

You can then return images/icons instead of strings. Just make sure you update both the appropriate Convert and CanConvert sections.

Upvotes: 4

Related Questions