Content within a user control - c#

I am almost too embarrassed to ask this question, but here we go...
I am not an expert with user controls, and need some design advise regarding trying to achieve a specific desired functionality.
The goal is to have a usercontrol that would render as a complex structure of html elements and css to form an elegant container box. The problem lies in how to populate the contents of the box as each instance of the usercontrol would have its own individual HTML content. The content container div of the usercontrol would be nested deep within the structure of the rendered html. It is undesirable to programmatically set the contents of the usercontrol, or use properties.
In psuedo-code, the desired syntax would be something like:
<usercontrol Title="Some Title"><p>some random html content</p></usercontrol>
A sample of the rendered usercontrol would be:
<div class="CommonBox">
<div class="Title">Some Title</div>
<div class="Content"><p>some random html content</p></div>
</div>
I hope my explanation is adequate. Does this make sense to anyone or is the desired functionality unachievable?
Cheers!
EDIT
I attempted the templated user control suggestion in the hopes of coming to a decent solution. I "waybacked" this site and now have a working templated user control. My next question is, how can I programmatically access the controls nested within the template... say there is a textbox control in the "Description" template from the example link and I want to set its value programmatically? Is this possible?

What you're looking for is definitely possible. One solution is to create a templated user control. In the end you can define the contents similar to how your example looks. Something like:
<uc:MyControl Title="Some TItle" runat="server">
<ContentsTemplate>
<p>some random html content</p>
</ContentsTemplate>
</uc:MyControl>
Here's a simple how-to. I've done this in the past with success. There are lots of resources found through Google as well on the topic.

Yes this is very possible. First you can create a custom control as I describe in this post. Properties in the control become attributes like "Title" you have in your example. Then you can extend your control with the technique shown in this post to add child nodes for the other html inputs you will require.
Enjoy!

It looks like you need two properties for your custom server control.
Title property to render first inner div's content,
Content for the second one. If you want to set contents inside your server control, you should use [PersistenceMode(PersistenceMode.InnerDefaultProperty)] attribute for your property, like this :
[PersistenceMode(PersistenceMode.InnerDefaultProperty)]
public string Contents
{
get
{
string contents = (string)ViewState["Contents"];
return (contents == null) ? String.Empty : contents;
}
set
{
ViewState["Contents"] = value;
}
}
PersistenceModeAttribute is explained in MSDN like that :
PersistenceModeAttribute Passing the
InnerDefaultProperty parameter
specifies that a visual designer
should persist the property to which
the attribute is applied as an inner
default property. This means that a
visual designer persists the property
within the control's tags. The
attribute can be applied to only one
property, because only one property
can be persisted within the control's
tags. The property value is not
wrapped in a special tag.
For more information take a look at the last example here.

Related

Best way to give element custom properties in C# Webform

I have a generic html element like this
<span v-bind:class="{ available: days.timeOne }" data-time="10:00" data-date="{{ days.date }}" class="home__visit-featured-days-item-buttons-time">10:00</span>
Which when it is being rendered, is having the vuejs tags being stripped.
I have encountered this issue before when using basic html elements and even control tags like and my solution was to add them manually in the code behind. I don't like this method as not only is long and tedious, it ties back end logic to the view.
Is there a attribute similar to ClientIDMode that I can use to stop these tags being stripped?
ASP.NET webforms will strip out attributes for server controls (those with runat="server") when attributes contain colon (:) characters because these attributes cannot translate to class properties in the back end. However, non-server controls (i.e. raw markup) should just render as written into the ascx file.
Your example doesn't have a runat="server" attribute so I would expect it to render as written. If, however, it is a server control, could you just use raw markup instead?
If it must be a server control I think your only option is to add your attribute in the code behind as you mention e.g. myControl.Attributes.Add("v-bind:class", "{ available: days.timeOne }");
I suppose you are using the CK Editor for entering the HTML code. I wouldn't recommend that since it's WYSIWYG and not a code editor and does such things as stripping some part of the source. If you can, please move your code to Static text web part or to the layout directly. If you need to have it inside the editable region area, you can specify protected source for the CK Editor to let it know what code not to touch:
https://www.google.com/search?q=ckeditor%20protectedsource&rct=j

Iterating over Sitecore Placeholder

I've been trying to iterate over a placeholder in sitecore. Essentially, there control that needs to be repeated by the page for a collection of elements (say a tab). I've only gotten the placeholder to render once. The following tabs don't have content inserted into them.
The code for something like what I'm trying to do is:
<asp:Repeater ID="rptTabs" runat="server">
<sc:Placeholder ID="plSocialSharing" runat="server" Key="Social"/>
<sc:Placeholder ID="plTab" runat="server" Key="content"/>
</asp:Repeater>
Should something like what I'm doing work? If it doesn't, do I need to user another sitecore control (something more dynamic?). Should I instead be using user controls I place there, or should I stick with the sitecore framework approach?
Since each of your tabs will contain the same rendering the I would not bother with placeholders. I think you will be adding more complexity than is required.
Assuming you are going to be using the jQuery UI Tab plugin then I would use the same technique you used in the previous question you asked, i.e. render out the content of the div tabs in the repeater, and you will need another repeater to create the ul list of the actual tabs.
Assuming you have a tree structure like:
- Social Sharing
-- Facebook
-- Twitter
-- Email
You could now Social Sharing use as the datasource of your Repeater and still allow the content of the tabs to be editable if you use Sitecore controls.
If you wanted something much more dynamic, like different rendering for each of the tabs, for example one with rich text, one with 2 column, one with table etc, then again there are a couple of ways of achieving this. One way would be to use standard <asp:PlaceHolder> in your repeater and add the rendering in this from your codebehind on ItemDataBound event.
Another option would be to add a bunch of different renderings into the placeholder in the page editor and set the datasource of each to content item. It will be difficult to use jQueryUI Tabs with this though since you would want markup like this in each control to make them self contained:
<div class="tab-title">Tab Title</div>
<div class="tab-content">Put whatever content you want in here</div>
As long as each rendering followed this structure then it would be easy to add several of these to the page and they would still be editable in the Page Editor, albeit listed one after another (not in tab format) in Editing mode. You would need to roll your own tab plugin, but it could be something as simple as:
Only in Preview or Normal mode
Get all .tab-title elements
Create a ul list and prepend to the tab container
Now call jQuery UI Tabs on the element
Hopefully given you some options at least, I can expand on any of these if it something you need but will have to get some code samples together.

How to get the text property of a hyperlink

There is no .Text property on hyperlink in WPF
looking to get the text in the click event and the only way so far is
Run r = hyperlink.Inlines.First() as Run;
gotText( r.Text );
Somehow this seems rather convoluted given that hyperlinks do have a text/content
Or is this an oversight or perhaps there's a better reason why this property does not exist ?
I believe that this is because a hyperlink can potentially have multiple runs of text.
This is because the Hyperlink control is derived from the TextElement Class. Specifically it is supposed to be a control that is able to sit within flow content. While one might initially view the control as something simple like a TextBox, but in order for the Hyperlink control to fit nicely within FlowContent it needs to have a similar structure to other flow content elements.
For more on FlowContent take a look at this.

HtmlGenericControl Without Tag

Asp.NET C#.
It is possible to create HtmlGenericControl without tag ? If i write :
HtmlGenericControl o_My_Control = New HtmlGenericControl();
It automatically returns a span element. I need an UserControl because i must add this control into an another usercontrol Control.Add(o_My_Control) and i need to directly append html. I use o_My_Control.innerHTML.
Can you help me to find solution ?
A HtmlGenericControl is a control used to represent an HTML element and thus it has to have a name. You can either provide one or if you don't it uses the default value of "span".
If you have some text you want to put into the page directly then you might want to look at the literalControl ( http://msdn.microsoft.com/en-us/library/system.web.ui.literalcontrol.aspx ). This control is designed to be used for "HTML elements, text, and any other strings in an ASP.NET page that do not require processing on the server".
So you could just do
myUserControl.Controls.Add(new LiteralControl(myHTMLstring));
And avoid needing to use the innerHTML at all.
A span element is automatically returned because all server controls are surrounded with span tags. There are several ways to go about removing these tags, but if you are able to write a custom control and then override the "RenderBeginTag" and "RenderEndTag" methods, you can solve the issue that way.
See http://weblogs.asp.net/gunnarpeipman/archive/2009/04/09/removing-span-tags-around-server-control.aspx for info on using this method to solve the problem.
Hope that helps.

Can I Re-Use Common Html in an ASP.NET Child Control?

I have 5 or so different pieces of HTML in my page that contain the same scaffolding HTML surrounding it, something like this:
//PanelBase.ascx
<div class="panel" id="[PANEL-SPECIFIC-ID]">
<h3>[PANEL-SPECIFIC-HEADER]</h3>
...
[PANEL-SPECIFIC-HTML]
...
</h3>
</div>
Where all the PANEL-SPECIFIC things are different for each panel type. Is there a way I can create a common base control to handle this scaffolding and inherit from it to supply the PANEL-SPECIFIC-HTML? The PANEL-SPECIFIC-ID and PANEL-SPECIFIC-HEADER I can just pass to the panel directly, but since the panel specific HTML is so large I don't want to pass it directly as a string.
Or is there some way to do it like this in each child control's ascx file:
<my:PanelBase PanelId="myChildPanel" Header="My Child's Header">
// HTML for my child panel.
</my:PanelBase>
Basically, I'm looking for some way to reuse the common portions of my control so I don't have to duplicate it for each child.
I guess the "most proper" way of doing this would be to have the main content of your container as a template, however that requires you to type <ContentTemplate></ContentTemplate> inside all your panels, which is less than ideal.
If I had to do this, I'd probably override AddParsedSubObject, collect any child controls into a collection and add them to a PlaceHolder or something similar in CreateChildControls. This can be done either with a custom control or a user control (.ascx).
For the headings and whatnot, just use Literals and create properties that wrap the Literal.Text properties.
Yes, and its generally good practice to do so. What would be ideal would be to put labels or literals in the places where you have content that would be modifiable. Then in the code behind you would put properties relating to each of them:
'These attributes allow you to specify individual properties about your control
'particularly if you want to be able to bind data to it, list it in the properties
'in your IDE, etc.
<BrowsableAttribute(True), Bindable(False), Category("Misc"), DefaultValue("true"), _
Description("Gets or sets the content title.")> _
Public Property DisplayContentTitle() As String
Get
Return _displayContentTitle
End Get
Set(ByVal value As Boolean)
_displayContentTitle = value
Me.litContentTitle.Text = value ' Optional
End Set
End Property
Then when you include the control in your page you would configure it in the following manner:
<asp:MyHtmlControl ID="blah" runat="server" DisplayContentTitle="Some text" />
This gives you the ability to modify, validate, manipulate or whatever in the code behind of the user control. It also allows the control itself to modified during runtime. You can also override loading and rendering events of your common control to perform specific actions based on any of these settings you create.
You might want to look into Nested Master Pages.

Categories