Creating ASP.NET composite control. How to apply properties associated with SkinID? - asp.net

I am creating a custom composite control based off of an asp:Label control. I'd like to be able to have the label's default properties be skinable as well as additional properties that I add to my control.
But when I add a skin definition to the Default.skin file in my themes directory, and add the control to my page with the SkinId specified, I cannot figure out how to get the control to render with the Skinned properties.
Additional points:
My custom control is defined in a separate library/dll.
I added one test property, and added the [Themeable(false)] attribute. Then I set that property in the .skin file. I didn't get any errors when I tried to view the page, so it appears to me that the .skin file is not getting applied or that the control def in the skin file doesn't get matched up with the control def in the aspx page.
From the skin file:
<ctrl:ExtendedLabel SkinId="test" runat="server"
Expandable="true" Lookup="true" Required="true"
RequiredCssClass="required" Text="Hello" />
From the aspx page:
<ctrl:ExtendedLabel SkinID="test" runat="server"/>
From web.config:
<pages>
<controls>
<add tagPrefix="ctrl" namespace="MyCompany.WebControls"
assembly="MyCompany.Web" />
</controls>
</pages>
I added a test property to the control, marked it as [Themeable(false)] in order to test if I'd get the runtime error when setting that property in the skin file. No error.
Notice that the pages tag doesn't have a styleSheetTheme attribute. I do however, have a Base page class that overrides StyleSheetTheme property, which seems to work for everything else.
If I add the styleSheetTheme attribute to the pages tag in web.config, the skin stuff works, including getting the error if I try to set the non-Themeable property.
What's the difference? How can I get it to work with the Base page class property code?

What are you getting when you try this? I just created a simple test project and was able to skin a custom property on a web custom control. My steps were:
Create the custom control.
Add [Themeable(true)] attribute to the class definition in the code-behind file.
Add a Label control to my custom control.
Add a property named "LabelText" to my custom control, which gets/sets the label controls Text value.
In web.config, add 'theme="TestTheme"' to the system.web/pages section.
In web.config, add '<add tagPrefix="mine" tagName="Test" src="~/UI/Test.ascx" />' to the system.web/pages/controls section.
In my Default.skin file, added '<mine:Test runat="server" LabelText="Test Text" />
In Default.aspx, added '<mine:Test id="test1" runat="server" />'
Load the page up and see the text "Test Text", which was only present in the Skin file.
Hopefully one of my steps above will be something you forgot, but if not, please update your question with details on what you are trying and what you are seeing.

Related

Setting static variable in compiled ASP.NET

I have compiled ASP.NET dynamic page with editable aspx pages.
I would like to some links to be generated upon changing some static variable
What i did is edit:
web.config as follows:
<appSettings>
<add key="currentEnvironment" value="dev-"/>
</appSettings>
and then
edited aspx page as follows
Home
But there is nothing appened when i try and run the .aspx page. Please help
You can't put a server tag inside another tag's markup like that, but you can just use the value directly. If you remove it and change the # to a =, it will work.
Home
Although if you can access the code behind, that would be a much cleaner way to do it, as in:
<asp:HyperLink ID="_index" runat="server">Home</asp:HyperLink>
and then set value from code behind
_index.NavigateUrl = String.Format("http://{0}www.mysite.com/web/index.html", ConfigurationSettings.AppSettings["currentEnvironment"]);

How to make .ascx properties settable in .aspx files

I have a user control that has a public property defined in the code-behind (.ascx.cs). Is there a way for this property to be set directly inside the tag of the .aspx file that the control is being used? I can already access the property in the code-behind of the .aspx file.
Unless I'm missing something obvious, then it's easy...
<uc1:MyCtrl runat="server" MyVal="this value" />

.skin vs .css from asp.net

What is the main difference between .skin and .css in asp.net?
.skin is new enhancement of IDE. I have been working with .css. What is available in .skin that is not to .css
thanks,
saj
In the skin file you can set properties of asp.net controls.
For example,
<asp:TextBox runat="server" Width="200"/>
All the TextBox controls in your application will have width 200.
You can give it a name and only the controls you like you can set them to apply a skin for example,
<asp:TextBox SkinID="MultiLineTextBox" runat="server" TextMode="MultiLine" Height="240"/>
now in a web page when adds TextBox control you can set its SkinID to be "MultiLineTextBox"
as the following,
<asp:TextBox runat="server" SkinID="MultiLineTextBox"/>
and thus it will inherit the TextMode as MultiLine and the Height as 240.
To use the skin you have to add a theme to your application under the App_Themes folder and there you add the skin file, now to use this theme in your pages you have to set the EnableTheming property of the page to true, StylesheetTheme or Theme to the name of your theme. You can also set this properties in the config file.
Setting the theme in the page aspx,
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" EnableTheming="true" StylesheetTheme="Your Theme Name" %>
Setting the theme in the web.config,
<configuration>
<system.web>
<pages styleSheetTheme="Your Theme Name"></pages>
</system.web>
</configuration>
Note that in terms of what these two things actually do there is a considerable difference. Any properties set in the .skin file are copied out to all of the page controls. An advantage to using Cascading Style Sheets is that the information is loaded and cached once. (and can be applied to multiple web pages.) Skin files can cause page bloat because all the properties set in the skin file must be merged with every affected control every time the page is rendered.
Additionally, the default behavior of the ASP.NET Theme .skin files is to override the properties of the controls being affected (this can be an unexpected behavior). For example, if you set the Width property for all ASP:Labels in your .skin file, all the ASP:Labels that use the skin file will have their Width properties set to that of the .skin file's regardless of the control's individual Width setting. To avoid this behavior, the ASP.NET StyleSheetTheme can be used to allow control-level properties to override the global .skin properties.
You can set some properties like Width even in CSS. Apart from being able to set properties that CSS cannot, there are some things you need .skin file for.
Consider an example where you need all the asp:Label controls on your page to be in blue color. A asp:Label is actually text inside a span, thats inside a hidden div. This is why we are able to set some properties like BackColor to this asp:Label and why the standard label control does not have a 'BackColor' property.
So, if you try to set font color to all ASP Labels through CSS,
then something like
Label {
color: Blue;
}
Will not work. On the other hand, using a skin file you can write
<asp:Label runat="server" ForeColor="Blue"></asp:Label>
and this will set all Labels to blue color.

Change UserControl template at runtime

Is it possible to change the ascx file used by a usercontrol at runtime?
For example in my page i have
<ctl:SampleControl runat="server" />
in the web.config I have
<controls>
<add tagPrefix="ctl" tagName="SampleControl" src="~/UserControls/SampleControl.ascx" />
</controls>
At runtime I would like to be able to change the ascx to another path, it would still be inheriting from the same usercontrol codebehind, it would just be a different template.
Probably the best thing to do here is to not encode the filename of the "default" .ascx file in your web.config. It will make your life harder. Always do that determination at runtime, like this for instance:
In your .aspx file:
<asp:PlaceHolder runat="server" ID="samplePH" />
In the code-behind:
string file = "~/UserControls/SampleControl.ascx";
if (condition)
file = "~/UserControls/OtherControl.ascx";
UserControl uc = (UserControl)LoadControl(file); // from System.Web.UI.TemplateControl.
samplePH.Controls.Clear();
samplePH.Controls.Add(uc);
But, be aware that in order for post-backs to work correctly, you need to instantiate the same control that was loaded on the last request, early in the page lifecycle -- typically the Init stage. This will ensure that viewstate is correctly parsed. Then, further down in your event handler, PreRender, etc. lifecycle steps, you can use the above code to load the UserControl for the current request.
If you really do need to encode a default page setting in a configuration file (for cases where end-users may want to change it), consider doing it in an app.config rather than buried away in a <controls> section of a web.config.
Documentation for the TemplateControl.LoadControl(string) method:
http://msdn.microsoft.com/en-us/library/system.web.ui.templatecontrol.loadcontrol.aspx

One Hyperlink In Many Different Locations

I'd like to implement a hyperlink in many locations on my website, however I just want to have it defined once not several times over. What is the best way to achieve this?
I started down the road of listing it in the node of web.config but I was only able to get that to list as a literal and wasn't successful in having it end up as a hyperlink.
I don't know much about master pages, but what I do know about them seems to me that they aren't the answer for this task because they wouldn't allow for that hyperlink to be located on some pages and not others and in different locations on some pages than others.
Help please! :)
I'm working in ASP.net VB.net
Put a HyperLink control on each page where you want it.
e.g. <asp:HyperLink runat="server" id="LogInLink">Login</asp:HyperLink>
Then either set the NavigateUrl property on the hyperlink in code-behind, e.g. this.LogInLink.NavigateUrl = Global.MySpecialUrl; or use <%=Global.MySpecialUrl%> notation to reference the value you want from your code in the NavigateUrl in the markup.
[Sorry, that's C# code]
You can create a custom control that inherits from HyperLink. This method will not require to use code-behind on individual pages but you will need to create a new class and modify your web.config file. Alter the namespaces as needed.
SpecialLink.vb
Namespace YourWebSite.Controls
Public Class SpecialLink
Inherits HyperLink
Public Sub New()
NavigateUrl = "~/SpecialLinkUri.aspx"
Text = "Special Link Text"
End Sub
End Class
End Namespace
web.config (add this to the system.web node)
This allows you to use this control on any page/master page/user control throughout your site
<pages>
<controls>
<add namespace="YourWebSite.Controls" tagPrefix="YourWebSite"/>
</controls>
</pages>
Using it on your page
<p>This is some text, here's the link: <YourWebSite:SpecialLink></YourWebSite:SpecialLink></p>
<p>This is some text, <YourWebSite:SpecialLink>here's the link</YourWebSite:SpecialLink>.</p>

Resources