locked
Selectively hiding fields in different page templates RRS feed

  • Question

  • User-632673987 posted

    I'm using code to hide fields in particular page templates using a custom metadata attribute based on this article

    The fields specified get hidden ok, but when inserting a record I get this error:

    Failed to load viewstate.  The control tree into which viewstate is being loaded must match the control tree that was used to save viewstate during the previous request.  For example, when adding controls dynamically, the controls added during a post-back must match the type and position of the controls added during the initial request

    I also have some business logic in a partial class for the DataContext which sets the field's value but it doesn't get called when I get the above error. This suggests that the field is in the model (something similar to Object Data Source, I'm not sure what Dynamic Data uses) and is being checked before the business logic gets called.

    Here's the code:

     HideColumnInAttribute.vb:

    Imports System
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Web
    Imports System.Web.DynamicData

    ''' <summary>
    ''' Define the HideColumnIn attribute and it's syntax
    ''' </summary>
    ''' <remarks></remarks>

    <AttributeUsage(AttributeTargets.[Property])> _
    Public Class HideColumnInAttribute
    Inherits Attribute
    Private _PageTemplates As PageTemplate()
    Public Property PageTemplates() As PageTemplate()
    Get
    Return
    _PageTemplates
    End Get
    Private Set
    (ByVal value As PageTemplate())
    _PageTemplates = value
    End Set
    End Property

    Public Sub New
    ()
    PageTemplates = New PageTemplate(-1) {}
    End Sub

    Public Sub New
    (ByVal ParamArray lookupTable As PageTemplate())
    PageTemplates = lookupTable
    End Sub

    Public Shared
    [Default] As New HideColumnInAttribute()
    End Class

    ''' <summary>
    ''' Define page templates in /DynamicData/PageTemplates
    ''' </summary>
    ''' <remarks></remarks>

    Public Enum PageTemplate
    Details
    Edit
    Insert
    List
    ListDetails
    ' add any custom page templates here
    End Enum

      

    HideColumnFieldsManager.vb:

    Imports System
    Imports System.Collections
    Imports System.Collections.Generic
    Imports System.Linq
    Imports System.Web.DynamicData
    Imports System.Web.UI

    Public Class HideColumnFieldsManager
    Implements IAutoFieldGenerator
    Protected _table As MetaTable
    Protected _currentPage As PageTemplate

    Public Sub New(ByVal table As MetaTable, ByVal currentPage As PageTemplate)
    _table = table
    _currentPage = currentPage
    End Sub

    Public Function
    GenerateFields(ByVal control As Control) As ICollection Implements IAutoFieldGenerator.GenerateFields
    Dim oFields = New List(Of DynamicField)()
    Dim Hidden As Boolean ' whether column should be hidden or not
    For Each column In _table.Columns

    ' show column if scaffolded, not a long string in a list page and not hidden
    If column.Scaffold = True Then
    Hidden = False
    If
    ((column.IsLongString = True) And (_currentPage = PageTemplate.List)) Then
    Hidden = True
    End If
    If
    column.IsHidden(_currentPage) = True Then
    Hidden = True
    End If
    Else

    Hidden = True
    End If

    If
    Hidden = False Then
    Dim
    f = New DynamicField()

    f.DataField = column.Name
    oFields.Add(f)
    End If

    Next
    Return
    oFields
    End Function
    End Class

    Public Module
    ExtensionMethods
    Sub New()
    End Sub
    <System.Runtime.CompilerServices.Extension()> _
    Public Function IsHidden(ByVal column As MetaColumn, ByVal currentPage As PageTemplate) As Boolean
    Dim
    hideIn = TryCast(column.Attributes.OfType(Of HideColumnInAttribute)().DefaultIfEmpty(New HideColumnInAttribute()).First(), HideColumnInAttribute)
    Return hideIn.PageTemplates.Contains(currentPage)
    End Function
    End Module

     

    ./DynamicData/PageTemplates/Edit.aspx.vb has this line added:

    ' reference HideColumnFieldsManager so we can customise fields to display based on a metadata attribute
    DetailsView1.RowsGenerator = New HideColumnFieldsManager(table, PageTemplate.Edit)

     

    and the metadata for the field is set like so:

      

    <HideColumnIn(PageTemplate.Edit)> _
    Public Property tktDateEntered() As Object
    Get
    End Get
    Set
    (ByVal value As Object)
    End Set
    End Property
     

     

    Wednesday, January 7, 2009 10:06 AM

Answers

  • User-797310475 posted

    ./DynamicData/PageTemplates/Edit.aspx.vb has this line added:

    ' reference HideColumnFieldsManager so we can customise fields to display based on a metadata attribute
    DetailsView1.RowsGenerator = New HideColumnFieldsManager(table, PageTemplate.Edit)

    The solution to your problem is to move the quoted code to Page_Init. Page_Load is too late.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 7, 2009 2:06 PM

All replies

  • User-1005219520 posted

    What happens when you disable viewstate? You might not need it.

    Wednesday, January 7, 2009 12:34 PM
  • User-797310475 posted

    ./DynamicData/PageTemplates/Edit.aspx.vb has this line added:

    ' reference HideColumnFieldsManager so we can customise fields to display based on a metadata attribute
    DetailsView1.RowsGenerator = New HideColumnFieldsManager(table, PageTemplate.Edit)

    The solution to your problem is to move the quoted code to Page_Init. Page_Load is too late.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Wednesday, January 7, 2009 2:06 PM