locked
Changing a Data Grid View column to enumeration when adding a new row RRS feed

  • Question

  • User-954539637 posted

    Hi All, 

    I have a database where one column should be populated from an enumeration of a few values. When I connect to the datasource in the GridView, it generates columns which in my case are all text. I want one of the columns to be a selection of enumerated values when we add a new row. So when the row is displayed from the database, I want that column to show the value (text). Then when the row is created, I want that column to be the selection from an enumerations. Or, I could have the column display the actual selected value in the database.

    This is my current data model ...

    namespace ServiceInstall
    {
    public enum ServiceType
    {
    Update,
    Create,
    Demand
    }
    public class ServiceConfiguration
    {
    [Key]
    public int Id { get; set; }

    // Name of the service
    [Required]
    [Display(Name = "Service Name")]
    public string SeviceName { get; set; }

    // Display Name
    [Required]
    [Display(Name = "Display Name")]
    public string DisplayName { get; set; }

    // Host
    [Required]
    [Display(Name = "Host/Machine Name")]
    public string MachineName { get; set; }

    // Type of service.
    // Update service - used after user has been created
    // Create service - used when a new user has been added
    // Demand service - used to demand a sync on a specific user
    [Required]
    [Display(Name = "Service Type")]
    public ServiceType Type { get; set; }

    [Display(Name = "Start-up Parameter")]
    public string Parameter { get; set; }

    }
    }

    So in the model above, I want my type column to be an enumeration selection when we add a new row, and show the actual selected value that was stored in the database.

    Any suggestions would be appreciated.

    Thanks,

    Tom

    Tuesday, January 15, 2019 5:19 PM

Answers

All replies

  • User475983607 posted

    The common approach is opposite of what you're doing.  Crafting a DB schema that support the enum lookup.  An enumeration is simply a distinct list of named constants.  So all you have to do is create table with an ID which is the enum value and a a VARCHAR to hold the name.  Query the database to set up the bindings.  When you need the enumeration in code, simply use Enum.TryParse().

    https://docs.microsoft.com/en-us/dotnet/api/system.enum.tryparse?view=netframework-4.7.2

    Of course it is up to you to sync the enum in the C# code base with the enum table.

    FYI, EF 6 has built-in enum support which syncs the code with the DB.  If you are building a new project then look into EF 6.

    https://www.google.com/search?q=Entity+Framework+6+enum&rlz=1C1GGRV_enUS812US812&oq=Entity+Framework+6+enum&aqs=chrome..69i57j0l5.9242j1j7&sourceid=chrome&ie=UTF-8

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, January 15, 2019 6:41 PM
  • User-893317190 posted

    Hi since3point0,

    One way to show enum in gridview is to use dynamic field, but you should use model bind to bind gridview and download  DynamicDataTemplatesCS using nuget.

    Below is a sample. As you could see you need to write little code about enum.

     <asp:GridView ID="GridView1" runat="server" AutoGenerateEditButton="true"  AutoGenerateColumns="false" SelectMethod="GridView1_GetData" ItemType="WebFormCases2.Models.school.ServiceConfiguration" UpdateMethod="GridView1_UpdateItem">
                <Columns>
                    <asp:BoundField  DataField="SeviceName" HeaderText="ServiceName"/>
                      <asp:BoundField  DataField="DisplayName"  HeaderText="DisplayName"/>
                      <asp:BoundField  DataField="MachineName"  HeaderText="MachineName"/>
                      <asp:BoundField DataField="Parameter" HeaderText="Parameter" />
                    
                    <asp:DynamicField DataField="Type" HeaderText="Type" />
                </Columns>
            </asp:GridView>

    My model

    public class ServiceConfiguration
        {
            [Key]
            public int Id { get; set; }
          
            public string SeviceName { get; set; }
         
           
            public string DisplayName { get; set; }
         
            public string MachineName { get; set; }
            [EnumDataType(typeof(ServiceType)), Display(Name = "Service Type")]
            public ServiceType Type { get; set; }
          
            public string Parameter { get; set; }
        }
    

    Code behind.

      ServiceDbContext serviceDbContext = new ServiceDbContext();
            protected void Page_Load(object sender, EventArgs e)
            {
            }
            public IQueryable GridView1_GetData()
            {
                return serviceDbContext.ServiceConfigurations;
            }
    
           
            public void GridView1_UpdateItem(int id)
            {
            }

    For more detail , you could refer to https://docs.microsoft.com/en-us/aspnet/web-forms/overview/presenting-and-managing-data/model-binding/updating-deleting-and-creating-data

    If you still want to use  original way to bind gridview , you could refer to the code below. It uses some methods of Enum.

       <asp:GridView ID="GridView1" runat="server" AutoGenerateEditButton="true"  OnRowEditing="GridView1_RowEditing" AutoGenerateColumns="false" OnRowDataBound="GridView1_RowDataBound" >
                <Columns>
                    <asp:BoundField  DataField="SeviceName" HeaderText="ServiceName"/>
                      <asp:BoundField  DataField="DisplayName"  HeaderText="DisplayName"/>
                      <asp:BoundField  DataField="MachineName"  HeaderText="MachineName"/>
                      <asp:BoundField DataField="Parameter" HeaderText="Parameter" />
                    
                   <asp:TemplateField HeaderText="Type">
                       <ItemTemplate>
                           <%# Eval("Type") %>
                       </ItemTemplate>
                       <EditItemTemplate>
                           <asp:DropDownList ID="DropDownList1" runat="server"></asp:DropDownList>
                       </EditItemTemplate>
                   </asp:TemplateField>
                </Columns>
            </asp:GridView>

    Code behind.

            ServiceDbContext serviceDbContext = new ServiceDbContext();
            protected void Page_Load(object sender, EventArgs e)
            {
                GridView1.DataSource = serviceDbContext.ServiceConfigurations.ToList();
                GridView1.DataBind();
            }
    
            protected void GridView1_RowEditing(object sender, GridViewEditEventArgs e)
            {
                GridView1.EditIndex = e.NewEditIndex;
                GridView1.DataSource = serviceDbContext.ServiceConfigurations.ToList();
                GridView1.DataBind();
    
            }
    
            protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
            {
                if(GridView1.EditIndex != -1)
                {
                    if (e.Row.RowIndex == GridView1.EditIndex)
                    {
    // get the dropdown without data DropDownList drop = e.Row.FindControl("DropDownList1") as DropDownList;
    // get all the values of ServiceTypeEnum, it will be [0,1,2] int[] values = Enum.GetValues(typeof(ServiceType)) as int[];
    // map the values to value+key using linq and Enum.GetName
    // the result will be { {"key":"Update", "Value":0} , {"key":"Create", "Value":1} , {"key":"Demand", "Value":2}} var enums= values.Select(v => new { key = Enum.GetName(typeof(ServiceType), v), value = v }).ToList(); drop.DataTextField = "key"; drop.DataValueField = "value"; // get the current model ServiceConfiguration con = e.Row.DataItem as ServiceConfiguration;
    // set the dropdown's selected value to the type of current model drop.SelectedValue = Convert.ToInt32(con.Type).ToString(); drop.DataSource = enums; drop.DataBind(); } } }

    The result.

    Best regards,

    Ackerly Xu

    Wednesday, January 16, 2019 3:14 AM
  • User-954539637 posted

    Thanks for your suggestion Ackerly. I considered it until I saw some support questions regarding DynamicDataTemplatesCS. So since I am at the beginning stages of development I decided to redo my database approach.

    Wednesday, January 16, 2019 2:41 PM
  • User-954539637 posted

    Thanks for the wake-up call. :-)  I took your advice and redesigned the database approach

    Wednesday, January 16, 2019 2:43 PM