There is so much confusion over what ViewState does and why is it required. Finally the following link helped me in understanding a lot of things:
Snippets from the above article:
Server Controls utilize ViewState as the backing store for most, if not all their properties. That means when you declare an attribute on a server control, that value is usually ultimately stored as an entry in that control's ViewState StateBag.
ASP.NET calls TrackViewState() on the StateBag during the OnInit phase of the page/control lifecycle. This little trick ASP.NET uses to populate properties allows it to easily detect the difference between a declaratively set value and dynamically set value.
When the StateBag is asked to save and return it's state (StateBag.SaveViewState()), it only does so for the items contained within it that are marked as Dirty. That is why StateBag has the tracking feature. In order for data to be serialized, it must be marked as dirty. In order to be marked as dirty, it's value must be set after TrackViewState() is called.
When the page first begins to load during a postback (even prior to initialization), all the properties are set to their declared natural defaults. Then OnInit occurs. During the OnInit phase, ASP.NET calls TrackViewState() on all the StateBags. Then LoadViewState() is called with the deserialized data that was dirty from the previous request. The StateBag calls Add(key, value) for each of those items. Since the StateBag is tracking at this point, the value is marked dirty, so that it may be persisted once again for the next postback.
ViewState is only one way controls maintain values across postbacks. Regular good old HTML FORMS play a role, too. For example, disable viewstate on a textbox, and it will still maintain its value, because it is POSTING the value with the form. Make that TextBox invisible then do a post, and the value is lost. Thats where ViewState helps, which would allow it to maintain the value even if its invisible.
The option to set control properties in the OnPreInit event in order to avoid those values from being entered into the viewstate is a good idea to avoid storing these values in the ViewState. To avoid Datagrids from storing values in the ViewState, rebind the data to the grid on each page load.