locked
Can ScaffoldColumn be different for Edit/Insert than for viewing? RRS feed

  • Question

  • User561814972 posted

    Actually, two questions. I think they are basic, but I'm new to Dynamic Data and I haven't been able to find an answer by searching, so sorry if it's been asked before.

    My goal is to have Last_Mod_Date and Last_Mod_By columns on my tables that are filled in automatically. I've already got that going using database triggers. (Is there a better way?) I'd like to hide those columns on the Edit or Insert forms, but display them on the List and Details forms. I am generating the code with Visual Studio 2012, using an ADO data model and the traditional .aspx page templating (not MVC), in C#.

    1. Is it possible, and if so how, to scaffold columns selectively, according to which .aspx page they are on?
    2. If it's not, I'll just hide them everywhere, but I'm still having trouble figuring out how to set the ScaffoldColumn attribute false. I can only find tutorials and help for doing this using MVC, which I'm not using. I think I'm supposed to create a new .cs module and further define the partial class for the table, but when I try to do that, I can't override the column object in my own .cs file to add the ScaffoldColumn attribute. I get "The type 'BCP2Essbase_Module.lkp_ess_SalesOffice' already contains a definition for 'last_mod_date'." I can only accomplish it by adding the ScaffoldColumn attribute in the generated partial class. That works, but of course is not the right way to do it because that code will be overwritten every time the model changes.

    I can post code on request.

    Any help is appreciated. TIA.

    Monday, May 22, 2017 6:00 PM

All replies

  • User2053451246 posted

    Research MetaData classes.

    https://forums.asp.net/post/5790438.aspx

    Monday, May 22, 2017 8:57 PM
  • User-330204900 posted

    No you cannot by default I had to write my own MetaModel based off the default one and my own attributes to do this. I will be publishing them to GitHub soon

    Tuesday, May 23, 2017 11:24 AM
  • User-1847166894 posted

    I think it will be enough creating two different entity templates (one for displaying the other one for CRUDing)

    Wednesday, May 24, 2017 5:36 AM
  • User1967761114 posted

    Hi johnbrk,

    According to your description,you want to hide some columns on insert/edit view,you could refer to the following code.

    (1) Create customizing attribute.

    //hide column attribute
    [AttributeUsage(AttributeTargets.Property)]
    public class HideColumnAttribute : Attribute
    {
      public PageTemplate[] PageTemplates { get; private set; }
     
      public HideColumnAttribute()
      {
        PageTemplates = new PageTemplate[0];
      }
     
      public HideColumnAttribute(params PageTemplate[] lookupTable)
      {
        PageTemplates = lookupTable;
      }
     
      public static HideColumnAttribute Default = new HideColumnAttribute();
    }
     
    //define page template enum
    public enum PageTemplate
    {
      Details,
      Edit,
      Insert,
      List,
      ListDetails,
    }

    (2) Create MetaColumn's extension method.

    public static class ExtensionMethods
    {
      public static Boolean IsHidden(this MetaColumn column, PageTemplate currentPage)
      {
        var hideIn = column.Attributes.OfType<HideColumnAttribute>().DefaultIfEmpty(new HideColumnAttribute()).First() as HideColumnAttribute;
        return hideIn.PageTemplates.Contains(currentPage);
      }
    }

    (3)Create class HideColumnFieldsManager extend from IAutoFieldGenerator.

    public class HideColumnFieldsManager : IAutoFieldGenerator
    {
      protected MetaTable _table;
      protected PageTemplate _currentPage;
     
      public HideColumnFieldsManager(MetaTable table, PageTemplate currentPage)
      {
        _table = table;
        _currentPage = currentPage;
      }
     
      public ICollection GenerateFields(Control control)
      {
        var oFields = new List<DynamicField>();
        foreach (var column in _table.Columns)
        {
        // carry on the loop at the next column  
        // if scaffold table is set to false or DenyRead
        if (!column.Scaffold || column.IsLongString || column.IsHidden(_currentPage))
           continue;
        var f = new DynamicField();
        f.DataField = column.Name;
        oFields.Add(f);
        }
        return oFields;
      }
    }

    (4)You could use the HiddenAttribute like this.

    public class Example
    {
            [HideColumn(PageTemplate.Edit,PageTemplate.Insert)]
            public string Description { get; set; }
    }

    (5) Edit view

    aspx:

    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
        <asp:DynamicDataManager ID="DynamicDataManager1" runat="server" AutoLoadForeignKeys="true" />
     
        <h2>Edit entry from table <%= table.DisplayName %></h2>
     
        <asp:ScriptManagerProxy runat="server" ID="ScriptManagerProxy1" />
     
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:ValidationSummary ID="ValidationSummary1" runat="server" EnableClientScript="true"
                    HeaderText="List of validation errors" />
                <asp:DynamicValidator runat="server" ID="DetailsViewValidator" ControlToValidate="DetailsView1" Display="None" />
                <asp:DetailsView ID="DetailsView1" runat="server" DataSourceID="DetailsDataSource" DefaultMode="Edit"
                    AutoGenerateEditButton="True" OnItemCommand="DetailsView1_ItemCommand" OnItemUpdated="DetailsView1_ItemUpdated"
                    CssClass="detailstable" FieldHeaderStyle-CssClass="bold">
                </asp:DetailsView>
                <asp:LinqDataSource ID="DetailsDataSource" runat="server" EnableUpdate="true">
                    <WhereParameters>
                        <asp:DynamicQueryStringParameter />
                    </WhereParameters>
                </asp:LinqDataSource>
            </ContentTemplate>
        </asp:UpdatePanel>
    </asp:Content>

    aspx.cs:

    protected void Page_Init(object sender, EventArgs e)
    { 
           //other statements
           //................
           DetailsView1.RowsGenerator = new HideColumnFieldsManager(table, PageTemplate.Edit);
    }

    (6) Insert View.

    aspx:

    <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
        <asp:DynamicDataManager ID="DynamicDataManager1" runat="server" AutoLoadForeignKeys="true" />
        <h2>Add new entry to table <%= table.DisplayName %></h2>
        <asp:ScriptManagerProxy runat="server" ID="ScriptManagerProxy1" />
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <ContentTemplate>
                <asp:ValidationSummary ID="ValidationSummary1" runat="server" EnableClientScript="true"
                    HeaderText="List of validation errors" />
                <asp:DynamicValidator runat="server" ID="DetailsViewValidator" ControlToValidate="DetailsView1" Display="None" />
                <asp:DetailsView ID="DetailsView1" runat="server" DataSourceID="DetailsDataSource" DefaultMode="Insert"
                    AutoGenerateInsertButton="True" OnItemCommand="DetailsView1_ItemCommand" OnItemInserted="DetailsView1_ItemInserted"
                    CssClass="detailstable" FieldHeaderStyle-CssClass="bold">
                </asp:DetailsView>
                <asp:LinqDataSource ID="DetailsDataSource" runat="server" EnableInsert="true">
                </asp:LinqDataSource>
            </ContentTemplate>
        </asp:UpdatePanel>
    </asp:Content>

    aspx.cs:

    protected void Page_Init(object sender, EventArgs e)
    { 
           //other statements
           //................
           DetailsView1.RowsGenerator = new HideColumnFieldsManager(table, PageTemplate.List);
    }

    Other templates such like Details,List or ListDetails are similar like Edit/Insert view.

    In List View template,you could modify like the following code:

    protected void Page_Init(object sender, EventArgs e)
     {
          //other statements
          //................
          GridView1.ColumnsGenerator = new HideColumnFieldsManager(table, PageTemplate.List);
    }

    If you have any other questions, please feel free to contact me any time.

    Best Regards

    Even

    Thursday, May 25, 2017 4:07 AM