How to make .ascx properties settable in .aspx files - asp.net

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" />

Related

How can I access an object inside of an asp:LoginView

I have a LoginView on a site master page that displays the username of the logged-in user. I modifies it to make the username a link to that user's settings, using a LinkButton.
I need to be able to conditionally enable or disable the LinkButton from within Page_Load. How do I get a reference to the LinkButton?
The LinkButton doesn't appear in the designer.cs file, but the LoginView does. I have tried looking at its controls property in the debugger and also tried using FindControl(LinkButton's ID) but that returns null.
--Jacob
You can't use the LogIn "as is", you have to create a LayoutTemplate inside the control.
<asp:Login ID="LoginUser" runat="server">
<%--the LayoutTemplate must include controls (with Text property)
with ID values UserName and Password--%>
<LayoutTemplate>
Your stuff here. Textboxes for user name and password, etc...
</LayoutTemplate>
</asp:Login>
Then you can find a control by
Label myErrorLabel = (Label)LoginUser.FindControl("logInErrorDetails");
Make sure that LinkButton is Asp.Net server control with "runat="server" attribute. If it is a server control then it should appear in your designer.cs file. Once it appeared in designer.cs file, you can access that control by its name or using FindControl method.
Some times Visual Studio IDE creates problem and it does not update desinger.cs file. Try to switch between designer view, mark up view and code view. It will update designer.cs file if the markup is correct.

Accessing text boxes in a web control on a master page

I need to access multiple textboxes on a master page. The textboxes are declared in a separate web control and it won't let me call the names of the textboxes so I can populate them with data. I have multiple textboxes like I said, but for example, when I try to write to txtName it will not let me even though when I click on the Design View it says it is there.
Can anybody help me out?
Expose the text boxes inside the web control as properties.
In webcontrol.ascx
<asp:TextBox runat="server" id="txtName" />
In webcontrol.ascx.cs
public virtual TextBox TxtName { get {return txtName;} //note capitalization
Then do the same thing in the master page to expose the web control.
In masterpage.master
<uc1:MyWebControl runat="server" id="MyWebControl1" />
In mastermage.master.cs
public virtual MyWebControl myWebControl{get {return myWebControl1;}}
Then make your master page strongly typed from the content page by adding a MasterType directive.
In default.aspx
<%# MasterType TypeName="MyMasterPageClass" />
Then you can access it from your content page code behind. In default.aspx.cs
Master.myWebControl.TxtName.Text="Hello, world!";
The reason it's necessary to do this is that controls declared on .aspx, .ascx, and .master pages are protected instead of public and there's no way (as of right now) to change them that I'm aware of. So we can use properties to expose these controls as public.

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

Binding custom class property of an ASP.NET control from ASCX markup

I have an ASCX that inherits from a WebControl that has a 'CustomConfiguration' property of type CollectionConfigurationItem. This configuration gets set elsewhere in the code, so by the time it gets to the ASCX it is set up to how I wish to use the data. At this point I'd like to render out another control using this configuration, like so:
<modules:DataModule runat="server" CustomConfiguration="<%# Model.CategoryListConfiguration %>" />
However, breaking into DataModule always results in 'CustomConfiguration' being null, which is the default value for the property. I've tried adding a Bindable attribute to the property but to no avail, and when I set an EventHandler for the DataBinding event on the DataModule it doesn't even get called.
How can I set this custom-class-typed property from the markup or, failing that what's the second-best method of getting this to work? Thanks for any light you can shed!
When you use the <%# %> syntax, it doesn't get executed until you databind the control. Try calling:
yourDataModuleID.DataBind();
e.g. from your Page_Init method.

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

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.

Resources