Load template from user control - c#

Im working with Sitefinity and I'm developing a Control Designer - however i dont think my question is specific to SiteFinity.
I have a class such as:
public class CaseStudyFeaturedItem : CaseStudySelectorControlDEsignerBase
The class it is inherriting from is itself inheriting from UserControl, like so:
public class CaseStudySelectorControlDesignerBase : System.Web.UI.UserControl {
Within CaseStudyFeaturedItem is it possible to load a template which is an embedded resource and then access the controls on that control?
So essentially, I have usercontrol.ascx which is an embedded resource so has a string like:
mynamespace.myclass.usercontrol.ascx;
And from within CaseStudyFeaturedItem I want to be able to load that usercontrol and then modify the controls (i.e. literals/labels) that are within it?
Is this possible?
Thanks
Al

We do this with every control in Sitefinity, but it would be a little complicated to do with your own custom controls (I assume you are using Sitefinity 3.7). The steps are the following:
- Implement a template container control, inheriting from GenericContainer:
protected class ItemListContainer : GenericContainer
{
public virtual Repeater RepeaterControl
{
get { return base.GetControl<Repeater>("repeater", true); }
}
}
- You need to get the template from the resource (use ControlUtils.GetTemplate method - Sitefinity does that for you):
public virtual ITemplate ItemListTemplate
{
get
{
if (itemListTemplate == null)
itemListTemplate = ControlUtils.GetTemplate(<virtual path to template>, <resource file name>,
<type to determine assembly for template>);
return itemListTemplate;
}
set
{
itemListTemplate = value;
}
}
- You need to call InstantiateIn method of the template, and pass it the container control
listContainer = new ItemListContainer();
ItemListTemplate.InstantiateIn(listContainer);
- Access all controls through the container
listContainer.RepeaterControl.DataBind();
In Sitefinity 4.0 we've included a base class for all controls, which will give you this functionality out of the box. In 3.7 though, you'll have to do all this by hand.
The ControlUtils class is in the Telerik.Framework.Web namespace. The code above is how this all is done in the ContentView control, you should probably make slight modifications depending on your case.
Cheers,
Slavo
The Sitefinity team # Telerik

Yes it is possible, but I'm not entirely sure what you're trying to accomplish based on your question. You can use LoadControl to dynamically load user controls. If you cast the result to the appropriate control type, you will then have access to all of its properties. From there, you can add it into whatever container you want to hold it. Is that the kind of thing you're trying to do?

Related

Can I use parent(web page) property in web user control?

How can I use parent(web page) property in web user control?
One more question:- How can I access the shared class(i.e. class in App_Code folder) property in web user control.
Thanks
You can use this.Page in asp.net user control to refer to page and it will always give you page in which that control is added.
You can access any public class declared in App_code folder directly in any user control without problem. Be careful of namespace and make sure to compile your project if you are having issues to access the class.
You could but I am not sure it would be a clean / full OOP approach, how about setting a public property or calling a public method of your user control from the page passing to it the value you need to use in the control?
this because the page hosting the control should be generic and is the page which contains the control not the other way round.
If this does not fit you, then you can take the control's Page property and cast it to the class of your page then you will be able to access its property but this will make your control specific instead of generic and it will only work when the control is hosted in pages of that exact type/class.
You have to mark the property as Public.
var myVar = ((ParentPageClass)this.Page).YourProperty;
To access the shared class you have to specify the namespace of that class:
YourProject.SomeNamespace.YourClass
or to include the namespace in your .ascx.cs file
using YourProject.SomeNamespace;
It's a cleaner aproach to pass the parameter to the user control from the parent page.

Handling Master Page Panels with Base Control Class

I have admin module. This module have one master page which has the no of panels at left side. I have to make this panels visible and invisible with base control class which is constructed in VB language. I'm working with asp.net 2.0 with c# web site.
Please give me idea how do i construct this base control class and manage panels with Master Page on link button click event.
We'll there is a plenty of opportunities to make it.
I'd prefer using of facade pattern.
Construct a class which would use VB class inside:
public newManageClass()
{
private oldManagedVBClass _old;
//.ctor
public newManageClass()
{
_old = new oldManagedVBClass();
}
public void makePanelsVisible()
{
_old.MakePanelsVisible();
}
}
And then you can use this class inside your master page as helper class.

Problem with Generate Local Resource and My simple custom control

I have created simple controls that are based on dot net controls . For example there is a simple GridView control that is based on dot net GridView control , I just set some setting in my control to use it in my .aspx pages , for example I set the Width of GridView in the constructor method :
// constructor of my custom class
public GridView(): base()
{
this.Width = new Unit(100, UnitType.Percentage);
}
and also I've added some custom properties :
public int SelectedID
{
get
{
if (ViewState["SelectedID" + this.ID] == null)
ViewState["SelectedID" + this.ID] = "-1";
return Convert.ToInt32(ViewState["SelectedID" + this.ID]);
}
set
{
ViewState["SelectedID" + this.ID] = value;
}
}
The *Problem* : when I use Tools>Generate Local Resource in VS2010
the aspx markup before I use this tool is like this :
<RPC:GridView ID="grdData" runat="server" onrowcommand="grdData_RowCommand">
but this tool adds any public property or any setting to my aspx markup , like this :
<RPC:GridView ID="grdData" runat="server" onrowcommand="grdData_RowCommand"
meta:resourcekey="grdDataResource1" SelectedID="-1" Width="100%">
I don't like VS2010 add my settings (like width) and my custom properties (like SelectedID) to aspx markup , this prevent me having the ability of changing my custom control code and reflect changes in all aspx pages that include this control , for example if
I change the width of my control to 50% , it doesn't reflect to any pages
Please tell me what should I do to fix my problem
Thank you very much for your feedbacks
This is a slightly complicated topic to address in one answer here to be honest! There are more than one approaches you can take to resolve this problem. It all depends on the kind of properties your control has and if it is a templated control or not. As a quick fix try decorating your public properties with the following attribute
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
or if you don't want the user to be able to set the public property at all via HTML markup then use
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
another attribute declaration which will be helpful with
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
is
PersistenceMode(PersistenceMode.Attribute)
I've found doing any initialisation in the ctor causes major headaches for local resource generation (even corruption). Use the DefaultValue attribute on properties and/or use OnLoad if possible. (As a side note use CSS rather than explicitly setting control width).

Custom formatting of validation errors & control tree issues - ASP.NET

I have a WebControl library I'm using to render out our stylized form elements. The library also contains some overriden validators, so that when used together, I can render out some nicer validation HTML/CSS than the default validator's red-star-next-to-a-field. Namely, I'd like to highlight the entire line.
At its most basic level, the 'form line' could render out:
Outer <div class="hasError">
<asp:Label>
<asp:TextBox>
(From there, there's all sorts of extra whistles, AssociatedControlID...)
The issue I'm having is that when having the control create its own overriden validator (e.g. controlled with a IsRequiredField property), I'm unable to get the validator's ControlToValidate to target the control itself.
It would seem the validator's target
ControlToValidate needs to be at the same level in the control tree.
And I can't add it to the Parent's
control tree during
CreateChildControls, as it gives an error.
... So I have a class like this:
[DefaultProperty("Value"), ValidationProperty("Value")]
public class BasicTextInputLine : WebControl, INamingContainer
{
...
private Label _someLabel;
private TextBox _someTextBox;
private MyRequiredFieldValidator _someValidator;
public string Value
public bool IsRequiredField
...
}
(Note - The ValidationProperty("Value") flag allows a validator to point at it)
and
public class MyRequiredFieldValidator : RequiredFieldValidator
{
...
protected override void OnPreRender(EventArgs e)
{
...
if (foundControlToValidate is BasicTextInputLine)
(foundControlToValidate as BaseFormEntry).IsValid = false;
}
Which I can happily works in markup like so:
<custom:BasicTextInputLine ID="foo" ... />
<custom:MyRequiredFieldValidator ControlToValidate="foo" ... />
Issue:
Unfortunately, I have a catch-22 when adding things to the control tree:
Adding it to the parent (which would give a working control tree) gives an error about not being able to interfere with its control set.
protected override void CreateChildControls()
{
...
Parent.Controls.Add(_someValidator);
}
And adding it to the control gives an error about the ControlToValidate not being able to be found.
protected override void CreateChildControls()
{
...
Controls.Add(_someValidator);
}
How can I structure this so I can have BasicTextInputLine create its own validator, and have it validate itself, not its inner TextBox?
Much appreciated.
I'm not sure whether I fully understand the problem, but as I interpret your code snippets, you are mixing two concepts here:
The BasicTextInputLine contains the validator directly. I derive that information in particular by the variable in the class:
private MyRequiredFieldValidator _someValidator;
and you trying to add it to the list of child controls.
The validator is a completely separated control, which refers to the main BasicTextInputLine. I can see that in your markup:
I think these two approaches are contradictory and you have two options:
Stick to approach 1. In that case, you should create the validator instance in your code, and remove the markup part.
Stick to approach 2. In that case, the BasicTextInputLine class does not need to know about the validator, i.e., remove the variable inside the class and don't create it as child control. You simply do not need it.

Inheriting a web server control in a simple fashion?

I'm having a Repeater used as a sort of Paging TagCloud. To do so, I've added simple properties to the Page's ViewState such as a Page, RowCount, etc...
I feel like it doesn't belong there but I had bad experiences with server controls, debugging, dll and deployment.
Could I just inherit the Repeater class, add a few ControlState/ViewState properties and be able to use it exactly as a Repeater dragged straight from the ToolBox?
Here, having the following simple class:
public class TagCloud : Repeater
{
public int selectedIndex;
public TagCloud()
{
selectedIndex = -1;
//
// TODO: Add constructor logic here
//
}
public int SelectedIndex
{
get { return selectedIndex; }
set { selectedIndex = value; }
}
}
Without creating a new WebControlLibrary project, could this cs file stands in the App_Code folder and work like expected?
Thanks.
Yes, there is no problem doing this. As long as you use the control's property syntax:
public int RowCount
{
get { return (int) (ViewState["RowCount"] ?? 0); }
set { ViewState["RowCount"] = value; }
}
Also, to make your properties look the same as the default ones you can add Description or DefaultValue attributes.
This works, and is one suggested way of building server controls. Try it and see.
Inheriting from the ASP Repeater is a completely valid approach, so long as the control you are building IS a repeater with additional properties.
If you feel the control you need is actually "something else" that happens to have a repeater as part of its control set, then you likely need to make a composite control which adds a repeater to its control collection, along with whatever other controls are needed.
For example, you might want to have a control that has a repeater, a label of search results, links to go to the top and the bottom of the repeater's contents, etc. This composite control is not a repeater, but does use a repeater.

Categories