views:

4564

answers:

7

When I disable ViewState for the page. It does not allow any other control to use ViewState .. even if I set EnableViewState="true" for that particular control ..

is it possible to enable ViewState for a control when ViewState is disabled for the page itself?

if not how can disable viewstate for controls on page except for few without specifying EnableViewState="false" explicitly .. typing the same into so many controls is hectic ..

+10  A: 

If you set turn page's ViewState off, then there is no way for you to enable ViewState for specific components. This is because ViewState is serialzed recursively, so when if the Page is not allowing ViewState, it will not serialize the ViewState for any of it's child controls.

In answer to your question, if you don't want to explicitly turn ViewState off on individual controls, but want to keep some controls ViewState aware, the best way would be writing a small utility method which turns ViewState off for all controls (using recursion or otherwise). Then enable ViewState for the controls that you would like to enable ViewState for.

Alternatively, a middle ground and less forceful way may possible if controls are groups inside other container controls (such as Panel). You can disable ViewState for all controls inside a Panel by disabling ViewState of the Panel.

Samuel Kim
Would the same concept work on a Placeholder? That'd get around the problem of having excess HTML tags generated.
Slace
Placeholder is only beneficial in text contents. If you have a calendar control and don't want to have ViewState, you don't want to use Placeholder and write the calendar HTML.
Samuel Kim
Its certainly and option, but turning off viewstate for the container would turn off viewstate for all child controls including lables.
Zuhaib
+2  A: 

Here's some code which expands on @Samuel Kim's concept of having a way to disable ViewState on all but certain controls (btw, it uses .NET 3.5):

List<string> allowedControls = new List<string> { "Control1", "Control3" };
IEnumerable<Control> controlsWithoutViewState = Page.Controls.Where(c => !allowedControls.Contains(c.ID));
foreach(Control c controlsWithoutViewState){
  if(c is WebControl) ((WebControl)c).EnableViewState = false;
}

The only thing I'm not 100% sure on (and I don't have my VM running) is whether Page.Controls needs to be cast or not, if so just have this instead:

IEnumerable<Control> controlsWithoutViewState = Page.Controls.Cast<Control>().Where(c => !allowedControls.Contains(c.ID));

The above is only a quick concept of what to do, it doesn't take into account nested controls where you may want 1 with and 1 without ViewState, but it wouldn't be hard to make a recusive function to handle it.

Slace
missing the `in` in the foreach
Naeem Sarfraz
A: 

You could also inherit from a BasePage. On the BasePage disable ViewState.

/// <summary>
/// All pages inherit this page
/// </summary>
public class BasePage : System.Web.UI.Page {

    protected override void OnLoad(EventArgs e) {
        base.OnLoad(e);
    }

    public bool ViewStateEnabled {
        get {
            return Page.EnableViewState;
        }
        set {
            Page.EnableViewState = value;
        }
    }

    public BasePage() {
        // Disable ViewState By Default
        ViewStateEnabled = false;
    }
}

In each page that you want ViewState Enabled, you do the following in Page_Load:

public partial class Products_Default : BasePage {
    protected void Page_Load(object sender, EventArgs e) {
        this.ViewStateEnabled = true;
    }
}

This should enable ViewState just for that Page (assuming it's ON in the MasterPage). Note: You will need to individually set each control's ViewState on that Page.

Atømix
A: 

I'm curious to see if Samuel's approach works. If you try it please post your result.

I'm not saying Samuel's wrong, I'd just be curious.

The reason I'm curious is because since viewstate is serialized recursively (as Samuel mentioned) if you had one control with viewstate enabled that was a child of a control with viewstate disabled, then the child control wouldn't have viewstate because the recursive serialization would skip over it entirely at the parent level. This would specifically be troubling if you have built your own user controls that would naturally contain a lot of child controls.

Another solution would be to use Samuel's utility method approach but instead of disabling everything, just disable it for controls like Label, Literal, etc that do not have children...or if they do have children it's ok if the children have viewstate disabled.

You would naturally want to avoid disabling the viewstate of Panels and Placeholders for the reason I stated above.

Edit:

Public Shared Sub DisableViewState(ByVal cntrl As Control)
    If TypeOf cntrl Is Label Then
        cntrl.EnableViewState = False
    ElseIf TypeOf cntrl Is Literal Then
        cntrl.EnableViewState = False
    ElseIf TypeOf cntrl Is Button Then
        cntrl.EnableViewState = False
    Else
        If cntrl.Controls IsNot Nothing Then
            For Each subControl As Control In cntrl.Controls
                DisableViewState(subControl)
            Next
        End If
    End If
End Sub
Adam
A: 

You can also subclass the built-in controls, and in your subclass set the EnableViewState property to false.

Mike C.
A: 

we cant do it in .NET 3.5

Ritu