ObjectDataSource methods can't refernce master page methods - asp.net

So I have ObjectDataSource that has an update and delete method associated with it and the DS is conntected to a gridview. When I call the methods, I want to repopulate a dropdown in the Master page that contains the same data as the grid, So i am trying to call the methods as follows:
MyApp MasterPage = (MyApp)Page.Master;
MasterPage.getData();
Now, if I do an insert from the grid (which is handled by the RowCommand event and not the DS) this works just fine, but thru the DS i get the following error: "Object reference not set to an instance of an object."
I can see certain fields on the aspx not being available yet from a postback, but how could a master page not be available to a page that is dependent on it? Shouldn't i be able to reference it? is there some backdoor trick to this? I know I could get rid of the DS, but I want to use it cause it makes paging and sorting so easy.
Thanks

Check the order of events in the masterpage-contentpage life-cycle. You might be able to move your code to an event that fires after the master page has access to the dropdown box.
EDIT: an alternative
If you can't move the code, try to store the data in a property of the master page, then, once the dropdown has been initialised, go back to the master page and get the data.
protected object SomePropertyICreatedToStoreData {get;set;}
void GetData()
{
// get the data (this part works already)
var theData = WhereTheDataComesFrom
// bind to dropdownlist - doesn't work, so...
this.SomePropertyICreatedToStoreData = theData;
}
... then later
this.MyDropDownList.DataSource = this.SomePropertyICreatedToStoreData;

You need to add the Master directive:
<%# MasterType TypeName ="MasterPageClassName" %>
or
<%# MasterType virtualpath="~/Masters/Master1.master" %>
http://msdn.microsoft.com/en-us/library/xxwa0ff0.aspx
Update: Separated TypeName and virtualpath as pointed out in the comments.

Related

ASP.NET User Control instance is null when referenced on Page_Load on page code behind

I have a user control that I have written and have added to an ASP.NET page, and functions just fine. However, I am trying to reference a property in the that custom control from code behind, on Page_Load, but cannot, because the variable, which is accessible, for the instance is null.
Is this normal for user controls and Page_Load? And if so, how can I make a reference to the control's instance in order to access its public properties? This is something I need to do before the page is rendered, in order to initialize some variables.
I had the same issue, and it turned out that I was registering my custom control incorrectly.
Correct Definition:
<%# Register Src="PeriodControl.ascx" TagName="PeriodControl" TagPrefix="ucs" %>
Incorrect Definition:
<%# Register TagPrefix="ucs" Namespace="MyWebsite" Assembly="MyWebsite" %>
The only difference was to reference the ascx file directly instead of the control in the assembly. Go figure!?
You can probably access your user control from the Page_PreRender event.
You can find more documentation about the page life cycle in asp.net here.

Control tree does not match viewstate during the previous request

Im debugging a quite complex system i did not code. On a post back i get this error:
Exception: 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.
Im not very familiar with how the viewstate loads and works. The code builds up some grid view and controls dynamicaly and inserts them into a placeHolder called phCallsDynamicGridHolder
The code that creates the exception is always something similar to this:
HtmlGenericControl summary = createNewCallsSummary(calls);
GridView gv = createGridView(calls, "Calls", width);
phCallsDynamicGridHolder.Controls.Add(summary);
phCallsDynamicGridHolder.Controls.Add(gv);
phCallsDynamicGridHolder.Controls.Add(createNewCallsTotalSummary());
Is anyone familiar with what causes this kind of exception? The page is almost 2000 lines of code, i will past as much as needed upon request.
Psychically debugging, I would guess you are doing that dynamic control creation on every request; you may want to try changing the code so you only do that dynamic control creation within:
if (!IsPostBack)
{
// here
}
Try to disable ViewState for this page.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind=" #####.aspx.cs" Inherits="#####" EnableViewState="false"%>

Can not get Request.Form.Get valus from aspx page that wrappe withe ContentPlaceHolder (form error)

I am writing a web app in asp.net I have a master page that contain a ContentPlaceHolder
and a form that wrapper the ContentPlaceHolder, In a aspx page I realize the ContentPlaceHolder and have some controls in this page.
Now when I Trying to use Request.Form.Get("my control name") (from the aspx behind code), I get null.
If I try to add a form in the aspx page I get an error that say you can have only one form in a page.
How can i get the values in my controls??
thanks for the help.
Request.Form("YourControlName") will not work with server controls because ASP.NET adds some extra stuff to the name of your control when it outputs it to the page. It does this to make sure that the name remains unique across all the controls on the page. So, for example, your control might actually be named something like "ctl00_maincontent_placeholder1_YourControlName" when it gets created on the page.
In ASP.NET this is not usually a problem because you typically do NOT use Request.Forms to get your control values. Instead you use the server control's methods to get the values. So, for a textbox, you would use YourControlName.Text to get the value that was entered into the textbox.
If you are just trying to communicate a value between the master and page, assuming the value is on the master you can cast Page.Master to the correct type. On the master page you can wrap controls on the master.
MasterPage
public string MyControlText
{
get
{
return myControl.Text;
}
set
{
myControl.Text = value;
}
}
On the page
((MyMasterPage)this.Page.Master).MyControlText = "To master from page";
string fromMasterToPage = ((MyMasterPage)this.Page.Master).MyControlText;

Container data values aren't coming through using a Templated User Control

I have created a Templated UserControl. I don't want to bloat this post by posting all the code I used to create the control but suffice to say that I am fairly certain that the code is correct. I will post a few snippets to show that I do know the proper way to do this. First is my ITemplate implementation:
private ITemplate _NutritionLabelTemplate = null;
[TemplateContainer(typeof(NutritionLabelContainer))]
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate NutritionLabelTemplate
{
get { return _NutritionLabelTemplate; }
set { _NutritionLabelTemplate = value; }
}
Then the implementation of my INamingContainer Interface:
public class NutritionLabelContainer : Control, INamingContainer
{
}
My template markup has a Placeholder control named "phNutritionLabel_Template" and cutting through the other blah blah blah, I've got something like:
phNutritionLabel_Template.Controls.Clear();
if (NutritionLabelTemplate != null)
{
NutritionLabelContainer nContainer = new NutritionLabelContainer();
nContainer.calcium = calcium;
nContainer.calories = calories;
NutritionLabelTemplate.InstantiateIn(nContainer);
phNutritionLabel_Template.Controls.Add(nContainer);
}
Afterward, I add this templated UserControl to my webpage and to test it I add the following code:
<uc1:NutritionalLabel_Template ID="NutritionalLabel_Template1" runat="server"
servingSize="28"
calories="46">
<NutritionLabelTemplate>
<h1>Template Calories</h1>
<span style="font-size:large; font-style:italic;"></span>
<asp:Label ID="Label1" runat="server">
<%#Container.calories %>
</asp:Label>
<br />
</NutritionLabelTemplate>
</uc1:NutritionalLabel_Template>
When I run the page the value of #Container.calories isn't visible, it's totally blank. I've debugged my code and stepping through it I can see that the values are clearly being set in the NamingContainer of the Templated Control and that the values are being carried over to the Placeholder via the NamingContainer.
I can also verify the values are set by placing the following code in the code-behind file of the webpage and then see the values reflected on the page. But otherwise, nothing.
Label1.Text = NutritionalLabel_Template1.calories;
I have seen this problem arise before and can't remember what the cause or resolution was. Can anyone provide any pointers?
I've only created these types of controls a few times so it's a bit new to me. Any help would be appreciated. I'm stumpped.
Thx
I never received any responses to this post so regardless of why no one could provide any clues to the problem, I figured out what the problem was and thought I'd post the solution for anyone who may potentially have the similiar issue to save you some needless frustration. ;-)
Turns out that I'd forgotten to add the DataBind() method to the Page_Load event of the default page. Per Microsoft, this method ensures a binding of data from a source to a server control and it's commonly used after retrieving a dataset through a database query. But since most controls perform data binding automatically, you typically should not need to make an explicit call to this method.
However, the method is also commonly overridden when you create a custom templated data-bound control. But in my case, I overrode the PageInit in the Templated control; not the Databind method. So apparently an explicit call should be made to the method in the calling page's Page_Load event to ensure the templated control and the data are bound in this case.

How does one get a code-behind file to recognize type of a user control?

I have a custom control in my mater page that represents a menu, let's call it CustomMenu. The control code files are located in a non special directory.
I want to give each page that uses that master page the ability to access the control and, using a public property, tell the control whether or not it should render itself.
I have a public property on the control to do that, and I know I can get the control by referencing Page.Master.FindControl('IdOfControlIwant');
The problem I'm having is that I can't seem to get the control Type recognized by the compiler, so when I do find the menu control, I can't actually work with it. The only way I can get the code behind to recognize the type is to register it in the ascx file, and then add at least one control to the page, which is undesirable.
Thoughts?
You have to combine what both Jacob and dzendras have posted. Add the MasterType directive to your content page's aspx file:
<%# MasterType VirtualPath="~/your.master" %>
And in the master page create a property:
public CustomMenu MyCustomMenu {get{ return myCustomMenu;}}
Where myCustomeMenu is the ID of the Usercontrol in your masterpage.
You should now be able to reference the usercontrol from a content page. So, if the CustomMenu usercontrol had a property called SelectedItem, you should be able to access it like this:
public void Page_Load(object o, EventArgs e)
{
Master.MyCustomMenu.SelectedItem = 1;
}
Use the MasterType directive in your pages:
<%# MasterType VirtualPath="~/your.master" %>
That will strongly type your Master page reference, so you should be able to add properties that can be accessed by the pages.
Make a property of your MasterPage class:
bool IsCustomMenuVisible {set{ CustomMenu.Visible = value;}}
And use it wherever you like.

Resources