How to display enum values in datagridview column

后端 未结 5 984
臣服心动
臣服心动 2021-01-18 02:30

I have this Database, not of my design but I have to work with it, that contains a table like so :

 id  |   Name     |  status  | ...
-----+------------+-------         


        
相关标签:
5条回答
  • 2021-01-18 03:07

    Currently, I don't quite understand what you mean by 1k items.

    But, all you have to do is create the enum for yourself like:

    public enum States
    {
         Invalid = 0,
         [Description("In developement")]
         Dev,
         Activ,
         Old,
         ...
    }
    

    And in your your formatting event you call this function

    /// <summary>
    /// Gets the string of an DescriptionAttribute of an Enum.
    /// </summary>
    /// <param name="value">The Enum value for which the description is needed.</param>
    /// <returns>If a DescriptionAttribute is set it return the content of it.
    /// Otherwise just the raw name as string.</returns>
    public static string Description(this Enum value)
    {
        if (value == null)
        {
            throw new ArgumentNullException("value");
        }
    
        string description = value.ToString();
        FieldInfo fieldInfo = value.GetType().GetField(description);
        DescriptionAttribute[] attributes =
           (DescriptionAttribute[])
         fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
    
        if (attributes != null && attributes.Length > 0)
        {
            description = attributes[0].Description;
        }
    
        return description;
    }
    

    that way

    e.Value = Enum.GetName(typeof(States), e.Value).Description;
    

    All you have to do is check that you have defined all the enum values that are possible, and that you're operating on the correct column.

    If you have 1000 values in your status column, there is nothing that can help you to automate this in .Net. But it's a job that has to be done once, so it's not that hard.

    0 讨论(0)
  • 2021-01-18 03:14

    I wouldn't do it on CellFormatting. I would attack the DataTable itself. I would add a row that has the type of the enum, and the loop through the table and add the values. Something like this:

        private void Transform(DataTable table)
        {
            table.Columns.Add("EnumValue", typeof(SomeEnum));
            foreach (DataRow row in table.Rows)
            {
                int value = (int)row[1]; //int representation of enum
                row[2] = (SomeEnum)value;
            }
        }
    

    Then, in your DataGridView just hide the column that has the integer representation of your enum.

    0 讨论(0)
  • 2021-01-18 03:22

    Since you say this DGV is "read-only", you could read the data table into a list of a custom type that performs the conversion in-place.

    You can get rid of the try-catch and your custom method and simply write:

    e.Value = ((StatusType)e.Value).ToString();
    

    If the value doesn't parse, it will be displayed as its integer value. That will speed things up a bit.

    0 讨论(0)
  • 2021-01-18 03:29

    You can use the CellTemplate property of the respective column. So first create a class for the cell template, overriding GetFormattedValue

    public class VATGridViewTextBoxCell : DataGridViewTextBoxCell
    {
        protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
        {
            Price.VATRateEnum r = (Price.VATRateEnum)(int)value;
            switch (r)
            {
                case Price.VATRateEnum.None: return "0%";
                case Price.VATRateEnum.Low: return "14%";
                case Price.VATRateEnum.Standard: return "20%";
                default:
                    throw new NotImplementedException()
            }
        }
    }
    

    then assign new instances of it to the columns' cell templates. Note that the change does not take effect until you refresh the grid and that's why I put it into the constructor:

    public frmGoods()
    {
        InitializeComponent();
        this.sellingVATDataGridViewTextBoxColumn.CellTemplate = new VATGridViewTextBoxCell();
        this.buyingVATDataGridViewTextBoxColumn.CellTemplate = new VATGridViewTextBoxCell();
    }
    
    0 讨论(0)
  • 2021-01-18 03:30

    You can use RowPostPaint event of DataGridView. You can do as following.

    private void TestGridView_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
          if(e.RowIndex == -1) return;
            TestGridView[YourColumnIndex, e.RowIndex].Value = YourEnumValue; // You can get your enum string value here.
        }
    

    In this method you need to check for the value you want to update otherwise this will throw you into infinite loop for updating the row. Once value is updated you should avoid updating it again. This solution is only applicable if this is readonly cell.

    I would suggest to go with BFree's solution, if that's not possible then you can think of this.

    0 讨论(0)
提交回复
热议问题