Answered by:
Selectively hiding fields in different page templates

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 EnumHideColumnFieldsManager.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 PropertyWednesday, 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