Unable To Render Control To Placeholder - c#

The following code will not add a control to an aspx placeholder:
var control = new ASCXControl { ID="searchFilters", Filters = filters };
var placeholder = Utility.FindControlRecursive(Page, "rightColumnSearchFilters") as PlaceHolder;
if(placeholder != null){
placeholder.Controls.Add(control);
placeholder.Visible = true;
}
When debugging, the placeholder is found and the control shows as added to the placeholder controls collection after entering the block, but yet I see nothing render into the placeholder on the page.
I currently need to pass variables to the control in order to find the filters I need to display. Although I don't like passing variables between controls, I don't see any other way.
What am I missing would make the control not render? Is there a better way to do this?
EDIT:
I am trying to get the HTML inside of the ascx to render. I am able to get the Filters parameters inside the Page_Load on the control.

This may or may not be the whole problem, but usually trying to instantiate a UserControl the way you're doing it leads to problems. You should do it using the LoadControl(path) method of the Page class:
ASCXControl ctl = (ASCXControl) LoadControl("path");
I'm not 100% sure, but I think that if you just instantiate it like an ordinary class/control, you wind up not running all the event handlers (such as Load) that you usually would.

Related

How to properly instantiate a Custom User Control from Code Behind

I created a custom user control that has the following table as part of it (and I've simplified slightly to make this easier to read):
<table id="tblWeekCalendar" runat="server">
<!-- .... -->
</table>
I'm trying to create the Custom Control from Code Behind on a different page:
// I'm passing values in on the constructor as an alternative to using attributes
MasterScheduleCalendar sch = new MasterScheduleCalendar(true, 123);
However, when I try to access tblWeekCalendar (the main table from my custom control) from the custom control's code-behind while constructing the control, I find that it is null:
HtmlTableCell tableCell = tblWeekCalendar.FindControl($"tdR{week}Day{day}") as HtmlTableCell;
This code runs in a method that's called from Page_Load.
I tried doing the following instead of directly calling the constructor, as in this question, but still the same problem:
MasterScheduleCalendar ctrl = (MasterScheduleCalendar)Page.LoadControl(typeof(MasterScheduleCalendar), new object[] { true, schedule.MasterScheduleID });
As mentioned previously, this occurs in a method that's being called from the Page_Load event handler, so I'm slightly baffled as to why tblWeekCalendar is null at this point. Does anyone have any suggestions as to how to fix this?
So you are doing it wrong.
Do not try to access "tblWeekCalendar" or any other element inside your control.
Implement methods that recive a values and update your control, or methods that get values when you need.
MyWeekOfTheDay week = tblWeekCalendar.GetWeekOfTheDay();
List<MyDays> days = tblWeekCalendar.GetViewDays();
List<MyMonth> months = tblWeekCalendar.GetCurrentYear().GetMonths();
Something like that.

How can I dynamically create a DIV in C#, add child elements to it, and then hide the DIV (and everything on it)?

I've found one way to skin this cat from this which led to this, but I'm wondering if it might be better to put all my "slide-uppable" elements on a div, and then slide up that div?
To be more specific, I'm creating controls in C# dynamically for a Sharepoint Web Page / Web Part. I conditionally need to hide or slide up "sections" of elements.
Theoretically (I think), I can create a DIV (Panel) like so (in C#, in my *.ascx.cs file):
Panel panelSec2 = new Panel(); // DIV
panelSec2.ID = "panelSection2";
... and then create the controls immediately thereafter like so:
boxRequesterName = new TextBox
{
CssClass = "dplatypus-webform-field-input"
};
...then add these controls to the DIV/Panel:
panelSec2.Controls.Add(boxRequesterName);
. . .
In this way (presumably/theoretically), I can hide/slide up the panel like so in jQuery in the corresponding *.ascx file:
$(document).on("change", '[id$=ckbxPaymentForSelf]', function () {
if (this.checked) {
var $panelSection2 = $('[id$=panelSection2]');
$(panelSection2).slideUp();
}
});
...and not have to worry about designating the individual controls for hidation/slidation.
Am I right? Or is there something wrong in my theory?
There's nothing wrong with your logic that I can think of.
One thing that might make things a little simpler on the JS side though would be to set the ClientIDMode to Static. Then you can use the more straight-forward '#ControlID' syntax instead of the attribute ends with syntax you've got now. You could also combine the two lines in the if statement to $('[id$=panelSection2]').slideUp()

Loading User Controls (ascx) from other User Controls

I have a UserControl (ascx) that, depending on the user's credentials, will load another UserControl (ascx). Currently the control to be loaded, contains a special navigation menu.
I am using this code:
UserControl jmNav =
(UserControl)Page.LoadControl("~/controls/client/jmNavigation.ascx");
Then, after some more code, I'm telling it to load, like this:
SBarTopWelcome.Controls.Add(jmNav);
The problem is, that I'm getting an "object reference not set to instance of an object" error.
Yes, the path is correct - as I tried it like this, as well (in all variations):
UserControl jmNav = (UserControl)Page.LoadControl("/client/jmNavigation.ascx");
This one (and its variants) tells me it doesn't exist.
So! Any thoughts?
One helpful solution is to add <%# Register %> to your parent control. Yes, I know it's in your parent page, but it should also be in your control.
If you do this, you should be able to Strongly-Type your control. For example, a control with a class name of MyControl would be:
MyControl controlVar = (MyControl)this.LoadControl("MyControl.aspx");
If you are able to get the stronly-defined variable, you should have no problems.
Inside SideBar.ascx add a place holder named SideBarTopWelcomePlaceHolder.
<asp:PlaceHolder ID="SideBarTopWelcomePlaceHolder" runat="server"/>
Then load jmNavigation UserControl to SideBarTopWelcomePlaceHolder like this.
Control jmNav =
Control Page.LoadControl("~/controls/client/jmNavigation.ascx");
SideBarTopWelcomePlaceHolder.Add(jmNav);
HA! I'm such a DORK! I was declaring the "SideBarWelcome" within a control like this:
public Control sideBarTopWelcome
{
get { return Page.FindControl("SideBarTopWelcome"); }
}
When I should have done it like this:
public Control sideBarTopWelcome
{
get { return FindControl("SideBarTopWelcome"); }
}
Without Page. Thank you anyway, guys. I appreciate it.

How do I assign an instance of the Image class to an Image control programatically?

Another noob question from me... Apologies!
My initial code would be as follows (this is simplified):
Image pic = new Image();
pic.ImageUrl = "~/Images/photo.jpg";
pic.BorderColor = "Black";
How can I assign the 'pic' Image object to an Image Control already on my ASP.NET page?
The following doesn't work but illustrates what I'm trying to do:
MyImageControl = pic;
I'm sure there must be an easier solution than:
MyImageControl.ImageUrl = pic.ImageUrl;
MyImageControl.BorderColor = pic.BorderColor;
If you want to dynamically put controls on the page you need to do just that. Have a container then add them to the container. If you have some sort of list or array that you are storing the controls in, you just need to iterate through the collection, setting any properties you need and call container.controls.add(control); You will have to do this every post-back as their state will not be kept.
Using an asp:Panel as your container where you want the controls to show up is the easiest way to style and position the controls.
SOLUTION (moved from original post) :
I have come up with something which works for me but would still be interested if there is a way to do what I've asked above - My solution is as follows.... Rather than having a blank Image Control in my .aspx page, I changed it for a PlaceHolder instead. Then, in the C# code, I can use the following to include my Image on the page:
MyPlaceHolder.Controls.Add(pic);

ASP.Net: User control with content area, it's clearly possible but I need some details

I have seen two suggestions for my original question about whether it is possible to define a content area inside a user control and there are some helpful suggestions i.e.
Passing in content to ASP.NET user control
and
ASP.NET User Control inner content
Now, I like the theory of the latter better than the former just for aesthetic reasons. It seems to make more sense to me but the example given uses two variables content and templateContent that the answerer has not defined in their example code. Without these details I have found that the example does not work. I guess they are properties of the control? Or some such?
EDIT - DETAILS: What I am trying to do
I have need of an ASP.Net user control that conceals some content in a panel inside a placeholder and asks for the input of a code in a visible panel.
Essentially the user will put their code into the provided textbox in Panel A and submit it, it will be checked and, if it is valid, panel B and the locked content will be displayed.
I have done a test where the content was hard coded into panel B but as soon as I need to make the content a generic input it fails. If it were just text or somesuch then I could make it a property of the control, but as it is, in fact, another User Control I am having some difficulty getting this into the "hidden" panel.
Any other workable solutions are also welcome.
EDIT NOTE: The solution I'm trying to implement this in 2.0 I did find a 3.5 solution which I cannot use.
The former example seems workable but I'd prefer to go with the latter if someone could fill in the blanks for me.
Thanks.
Okay, so this is disturbingly easy but many of the tutorials on the web that talk about this kind of thing push to do extravagant things that require the control to parse ListItems or such.
So this solution is purely so that you can build a control that, for whatever reason, has a placeholder in it that could have anything inside it (kind of like a content area on a Master page). In this instance it happens to be because the Panel containing the placeholder is hidden until appropriate input actions have taken place in another panel.
First, you need to add this:
[ParseChildren(true,"Content")]
[PersistChildren(false)]
just above the part of the control which looks like this:
public partial class MyControl : System.Web.UI.UserControl
then in the control scoped declarations at the head of the control you want to declare thus:
private Control _content;
[PersistenceMode(PersistenceMode.InnerProperty)]
public Control Content { get { return _content; } set { _content = value; } }
Finally you need to place the content into the placeholder like this:
phContent.Controls.Add((Control)_content);
That last line goes into the Page_Init event. For reference "phContent" is the name of the place holder where you want the content to appear, like this:
<asp:Panel ID="pnlLockable" runat="server" Visible="False">
<asp:Placeholder runat="server" ID="phContent" />
</asp:Panel>
On the front end the resulting implementation looks like this:
<uc:MyControl runat="server" ID="lockit1">
<Content>
//...your stuff goes here...
</Content>
<uc:MyControl>
Note that I presume that what is inbetween the Content Tags is a root control. This is because I nested another user control in there. I imagine if you put whatever content you want within a panel or placeholder it should be fine.
Also you can read "How to: Create Templated ASP.NET User Controls". Really helpful.

Categories

Resources