How can I dynamically access user control attributes? - asp.net

Im trying to create a "user control menu" where links to a page's usercontrols are placed at the top of the page. This will allow me to put several usercontrols on a page and allow the user to jump to that section of the page without scrolling so much. In order to do this, I put each usercontrol in a folder (usercontrols) and gave each control a Description property (<%# Control Language="C#" Description = "Vehicles" .... %>).
My question is how can I access this description dynamically? I want to use this description as the link in my menu. So far, I have a foreach on my page that looks in the ControlCollection for a control that is of the ASP.usercontrols type. If it is I would assume that I could access its attributes and grab that description property. How can I do this? (Im also open to a better way to achieve my "user control menu", but maybe thats another question.) Should I use ((System.Web.UI.UserControl)mydynamiccontrol).Attributes.Keys?

you can iterate over the collection and do either a switch or a few if statements
I would suggst you have an interface or an abstract base class for all your user controls:
public abstract class MyBaseClass : UserControl
{
public abstract string MyDescription {get;}
}
public MyUserControlA : MyBaseClass
{
public string MyDescription {get {return "my description";}}
}
public MyUserControlB : MyBaseClass
{
public string MyDescription {get {return "my other description";}}
}
Then you can loop over them as you do:
foreach ...
if (mydynamiccontrol is MyBaseClass)
{
Response.Write(((MyBaseClass)mydynamiccontrol).MyDescription);
}
Hope this helps

Related

How two read one user control label text in another use control?

I am using two user controls in my web application. I want to read a Label text from a user control via another user control. How can i read it?
You should refactor your code and not rely to content of some label on another UI control. Get that value the same way as you do in that User Control, or extract that functionality in another class to avoid code duplication, and call it from both places.
But, if you wont to stick with this existing code you should create Interface and capture all UserControls functionality that you wont to called from outside code (in your case : return label text). Then implement that interface in User Controls that must be called from outside, after that is all about finding control instances, you can do that by enumerating all Page child controls. Here is the example code of simple interface that defines that control must return some Label text, and a class that finds user control by name in control tree :
public interface IUserControl
{
string LabelText();
}
public class PageUserControls
{
private Page parentPage;
public PageUserControls(Page myParentPage)
{
this.parentPage = myParentPage;
}
private IEnumerable<Control> EnumerateControlsRecursive(Control parent)
{
foreach (Control child in parent.Controls)
{
yield return child;
foreach (Control descendant in EnumerateControlsRecursive(child))
yield return descendant;
}
}
public IUserControl GetControl(string controlName)
{
foreach (Control cnt in EnumerateControlsRecursive(this.parentPage))
{
if (cnt is IUserControl && (cnt as UserControl).AppRelativeVirtualPath.Contains(controlName))
return cnt as IUserControl;
}
return null;
}
}
then you have to implement that interface in user control that holds that Label :
public partial class WebUserControl1 : System.Web.UI.UserControl, IUserControl
{
public string LabelText()
{
return Label1.Text;
}
}
And finally use it from another User control :
PageUserControls puc = new PageUserControls(this.Page);
string txt1 = puc.GetControl("WebUserControl1.ascx").LabelText();
btw. method EnumerateControlsRecursive is adopted from SO answer to Finding all controls in an ASP.NET Panel?
use like this...
create one public property in the user control and call that property using user controls name where you want that value....
Take a look at this article on MSDN.
In a short, you can access other controls if you know the ID.

ASP.NET MVC2: modifying master css property depending on query string parameter

I am migrating a web site to a new one using ASP .NET MVC2.
In the original site, master page has code-behind to check a query string parameter value. Depending on this value, code-behind dynamically modify some CSS property to hide / display master page elements.
As MVC2 has no code-behind because we are supposed to perform everything in the controllers, how should I proceed in this case ?
I see this : asp.net mvc modifying master file from a view
It partially answers my needs but the query string processing is common to all pages. How can I move this processing in a common code section ?
Regards.
A helper method looks like a good place:
public static class HtmlHelperExtensions
{
public static string GetCss(this HtmlHelper htmlHelper)
{
// read some request parameter
// here you also have access to route data so the
// parameter could be part of your custom routes as well
var foo = htmlHelper.ViewContext.HttpContext.Request["foo"];
// based on the value of this parameter
// return the appropriate CSS class
return (foo == "bar") ? "barClass" : "fooClass";
}
}
And somewhere in your master page:
<body class="<%= Html.GetCss() %>">
Or if you are always going to apply it to the body tag only it might be more appropriate to do this in order to reduce the tag soup:
public static class HtmlHelperExtensions
{
public static MvcHtmlString StartBody(this HtmlHelper htmlHelper)
{
var body = new TagBuilder("body");
var foo = htmlHelper.ViewContext.HttpContext.Request["foo"];
var bodyClass = (foo == "bar") ? "barClass" : "fooClass";
body.AddCssClass(bodyClass);
return MvcHtmlString.Create(body.ToString(TagRenderMode.StartTag));
}
}
and in your master page at the place of the body tag:
<%= Html.StartBody() %>
I can think of two solutions to this:
Derive your controllers from one controller base and set the ViewData parameter there depending on posted Form values
Don't use ViewData at all, but simply look for the form value in the view (using HttpContext.Current)
The second method violates the MVC pattern. IMO it is still acceptable in some scenarios, for example I am using this approach to highlight the currently selected item in a navigation menu.

Changing the generated ASP.Net <form> id?

In my ASP.Net page I have
<form id="MasterPageForm" runat="server">
However, whenever the markup is generated, it turns into
<form name="aspnetForm" method="post" action="SomePage.aspx..." id="aspnetForm">
Is it possible to set what the generated HTML id for the form is?
Note: you are seeing "aspnetForm" because you are using a master page.
I found your solution in this thread...
http://forums.asp.net/p/883974/929349.aspx
In short, this is what the answer is from that link:
Here's the responsible code for that error:
public override string UniqueID
{
get
{
if (this.NamingContainer == this.Page)
{
return base.UniqueID;
}
return "aspnetForm";
}
}
As you can see, when the naming container is different from the current page (something that happens when you use a master page) the UniqueID property return "aspnetForm". this property is rendered into the name attribute that is sent to the client in the form tag. so, if you really need to, you can create your own form by inheriting from htmlform and then override the UniqueID property or the Name property (this may be a better option).
An example custom HtmlForm class could be like this:
public class Form : System.Web.UI.HtmlControls.HtmlForm
{
public Form() : base() { }
public override string UniqueID
{
get {
if (this.NamingContainer == this.Page)
{ return base.UniqueID; }
return "f";
}
}
}
Note: You can certainly change the name of the form from "f" to something else, or have it read a dynamic value, say from a web.config file or so.
and used like so
<%#Register tagprefix="LA" Namespace="Mynamespace"%>
...
<LA:form runat="server" id="frm">
...
</LA:form>
Set the "clientidmode" attribute to "static" on the form tag to prevent the framework from overriding it with "aspnetForm". This was driving me nuts for hours.
I am agree with #Sumo's comment under accepted answer and I had the same situation.
In ASP.NET 4.0, master page, if a is not given an id, the rendered html will be automatically assigned one, such as .
Otherwise, the rendered html will have its original defined id.
change in web config
<pages controlRenderingCompatibilityVersion="4.5" clientIDMode="AutoID"/>
to
<pages controlRenderingCompatibilityVersion="4.5"/>

How do I make a custom ASP.NET control based/subclassed on an existing one?

I want to make a custom ASP.NET control that is a subclasse of System.Web.UI.WebControls.Calendar. I need it to add a few data members and set up a few event handlers in it's constructor.
Is this possible? If so How?
So far I have tried using add new item to add a default web user control and tried editing in Calendar in a few different places. None have worked so far.
Edit: it seems I'm totally missing how this stuff is supposed to work.
Does anyone known of a demo project that I can look at? Something that already exists. (Unless you are really board, don't go out and make one for me.)
Unless I'm misunderstanding the question, you can just create a new class file and inherit from Calendar. Add in the properties you need, and the event handlers you want to set up.
public class MyCalendar : System.Web.UI.WebControls.Calendar
{
public MyCalendar()
{
// set up handlers/properties
}
}
Then anywhere you'd like to add a Calendar to your pages, you can simply create a MyCalendar instead. If you need to do so in the designer, you can look at several good tutorials about how to make your inherited controls show their new properties in the designer, like this one.
In a new class file you need to inherit from System.Web.UI.WebControls.Calendar instead of System.Web.UI.UserControl.
namespace MyNamespace
{
[ToolboxData("<{0}:UserCalendar runat=\"server\" />")]
public class UserCalendar : System.Web.UI.WebControls.Calendar
{
private string property1;
public UserCalendar() { }
public string Property1 { get { return property1;} set { property1 = value; } }
}
}
Then on your .aspx page (or in another control .ascx):
<%# Register TagPrefix="userControl" namespace="MyNamespace" assembly="MyProjectAssembly" %>
<userControl:UserCalendar runat="server" ID="myCalendar" property1="some value" />
Stuff to read: Developing Custom ASP.NET Server Controls.

How to get design surface rendering and design time datasource selection with an asp.net user control

If I create a user control (EDIT:not a web control/server control) it's pretty trivial to get databinding. I just add a datasourceID property.
In code behind (vb)
Partial Public Class BandedControl
Inherits UserControl
Public Property DataSourceID() As String
Get
Return MyGridView.DataSourceID
End Get
Set(ByVal value As String)
MyGridView.DataSourceID = value
End Set
End Property
End Class
In code behind (c#)
public partial class BandedControl : UserControl
{
public string DataSourceID {
get { return MyGridView.DataSourceID; }
set { MyGridView.DataSourceID = value; }
}
}
My issue is that this breaks design time rendering and also I don't get a drop down list to choose my datasource. How do I resolve this. (Hint: I think I need a type convertor, but all the info I can find relates to server controls not user controls).
You could try adding the IDReferenceProperty attribute to your property definition...
public partial class BandedControl : UserControl
{
[System.Web.UI.IDReferenceProperty(typeof(DataSourceControl))]
public string DataSourceID
{
get
{
return MyGridView.DataSourceID;
}
set
{
MyGridView.DataSourceID = value;
}
}
}
See http://msdn.microsoft.com/en-us/library/system.web.ui.idreferencepropertyattribute.aspx for more info about the IDReferencePropertyAttribute class.
If that doesn't work - I'd also try to inherit from DataBoundControl instead of UserControl and see if that gets you anywhere.
Web UserControls are compiled dynamically at run time and so are not rendered at Design time, what you want to do is create a Web Custom Control. Your best bet here is to extend one of the existing Bindable Web Controls
http://msdn.microsoft.com/en-us/library/aa651710(VS.71).aspx
Not sure if this is exactly what you want but I seem to remember them showing something similar to this in some dnr tv episodes.
I think it was Miguel Castro episodes 1 & 2, but it could be episode 31.
An archive of all the videos is here

Resources