How to use ClientIDMode in ASP.NET 4 - asp.net

The default value of ClientIDMode for a page is AutoID. The default
value of ClientIDMode for a control is Inherit. If you do not set
ClientIDMode for a page or for any controls on the page, all controls
will use the AutoID algorithm.
This is from msdn. But when I created a web application in ASP.NET 4 or even 3.5, all of the ids of the control are what I have written for them. They are not generated by the autoId algorithm. Then I tried to manually add clientIDMode="AutoID" to the controls, it also doesnt work what I was expected. So what is the problem ? Is there any rule to make it available ?
Thanks in advance,
EDITED
This is in .aspx page
<div>
<asp:Panel ID="Panel1" runat="server">
<asp:Panel ID="Panel2" runat="server">
<asp:Panel ID="Panel3" runat="server">
<asp:Panel ID="Panel4" runat="server">
(:
</asp:Panel>
</asp:Panel>
</asp:Panel>
</asp:Panel>
</div>
This is output:
<div id="Panel1">
<div id="Panel2">
<div id="Panel3">
<div id="Panel4">
(:
</div>
</div>
</div>
</div>

The reason you are getting all your Id's coming out the way you are is because there is no reason for the .NET framework to change them.
If you had placed your Panel's within a Repeater control, then they would all change to avoid multiple ID's of the same name.
Example (not correct markup):
<asp:Repeater id="repeater1" runat="server">
<template>
<asp:Panel id="Panel1" runat="server">
<asp:Panel id="Panel2" runat="server">
</asp:Panel>
</asp:Panel>
</template>
</asp:Repeater>
Your HTML which is generated from this would show that the Panel id's have been changed to inherit from the containing control. Something like repeater1_ct100_Panel1
The same happens when you are using Master Pages, Content Holders, and DataBound Controls. .NET updates the ID's to avoid multiple ID's of the same name.

The differences between the different ClientIDMode values can be clearly seen if you nest one control into another; the AutoId mode names the control after each parent naming container, while the Static mode starts a new naming hierarchy. Predictable mode is mostly used with data binding controls, while Inherit mode causes the control to use its parent's ClientIDMode.

Related

asp:Menu stops working after a different control performs partial AJAX postback

This issue occurs in ASP.NET 4.6 and I've seen a few similar posts, but they usually referred not to the same control (built-in here) or ended up with a conclusion "just use a different/external control here: html link", which is not really an option for me.
First, some code
Site.Master
<div id="HeaderProper">
<div id="HeaderProperTitle">
<asp:Menu ID="HeaderProperMenu" runat="server" DataSourceID="HeaderProperSiteMap" Orientation="Horizontal"
BackColor="#ff2400"
RenderingMode="List"
StaticEnableDefaultPopOutImage="false"
StaticDisplayLevels="2"
StaticHoverStyle-BackColor="#000000"
StaticMenuItemStyle-HorizontalPadding="15px"
StaticMenuItemStyle-Height="42px"
DynamicHoverStyle-BackColor="#000000"
DynamicMenuItemStyle-HorizontalPadding="5px"
DynamicMenuItemStyle-BackColor="#ff2400"
DynamicMenuItemStyle-Font-Size="24px"/>
<asp:SiteMapDataSource ID="HeaderProperSiteMap" runat="server" />
</div>
SomePage.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h1>Complete List</h1>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<div class="SortOrderSelection">
Sort by
<asp:DropDownList ID="cbxSortBy" runat="server" AutoPostBack="true"
OnSelectedIndexChanged="cbxSortBy_SelectedIndexChanged" />
</div>
<asp:Panel ID="SortedList" CssClass="top-margin five-columns" runat="server" />
<asp:Panel ID="Summary" CssClass="top-margin" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</asp:Content>
How to reproduce:
Choose an item in the DropDownList, which causes partial postback. The menu then stops working, that is - the drop down/hover menu doesn't open, but the first level links seem to be functional. Refreshing the whole page fixes the problems (duh?).
And, contrary to what I've found:
1) Menu is NOT inside an UpdatePanel, which I acknowledge is unsupported solution
2) Menu works fine when RenderingMode is set to Table, but generates a very ugly html code, which I would like to avoid. Not mentioning additional quirks in margins that have to be adjusted with ugly fixes.
3) I tried setting z-index: 1000...0 !important as suggested by some sources (on most menu related styles), but to no avail.
I would be grateful for any suggestions how this can be resolved while still using asp:Menu control in List rendering mode, possibly with as least intervention as possible. My point here is to use built-in functionality and keep the code clean from unnecessary JS, jQuery (if possible at all; otherwise I'd rather open a Connect case for this issue).
Thank you in advance.
Putting your menu into an update panel should work because it will indicate to the server to update it after the postback. Without this, any repost can create the risk of losing some events in your element. Refreshing works because you are refreshing the whole page and not only some element of it.

Reusing ASP.NET Controls in Multiple Views

Is it possible to reuse asp.net controls in multiple views within a MultiView? I would like to provide my customers the option to view and entry form as either a ASP.NET Wizard or as a Form depending on their preference. Most of my research has resulted in numerous hits for MVC, but I'm using WebForms and can't find a definitive answer either way.
My theory is that this should be possible, but since the control is already defined elsewhere on the page, I ought to be able to simple tell it to re-display the same control at a different location.
For Example something like this perhaps:
<asp:MultiView ID="mv" runat="server" ActiveViewIndex="0">
<asp:View ID="WizardView" runat="server">
<asp:Wizard ID="wizzy" runat="server" ActiveStepIndex="0">
<WizardSteps>
<asp:WizardStep ID="WizardStep1" runat="server">
<!-- Wrapped in PlaceHolder goodness :P -->
<asp:PlaceHolder ID="wPH1" runat="server">
<asp:Label ID="MyLabel" runat="server" Text="Hello Stackies"></asp:Label>
</asp:PlaceHolder>
</asp:WizardStep>
</WizardSteps>
</asp:Wizard>
</asp:View>
<asp:View ID="FormView" runat="server">
<form action="#" method="post" id="wizzyform">
<!-- I WANT TO REUSE THIS CONTROL HERE -->
<asp:PlaceHolder ID="fPH1" runat="server"></asp:PlaceHolder>
</form>
</asp:View>
</asp:MultiView>
UPDATE WITH ANSWER!!
I simply added some PlaceHolders to my Markup and created a toggle button in my VB.NET Codebehind with the following.
Protected Sub ToggleView() Handles ViewToggleBtn.Click
If RequestWizard_mv.ActiveViewIndex = 0 Then
ViewToggleBtn.Text = "Toggle Wizard View"
RequestWizard_mv.ActiveViewIndex = 1
fPH1.Controls.Add(wPH1)
ElseIf RequestWizard_mv.ActiveViewIndex = 1 Then
ViewToggleBtn.Text = "Toggle Form View"
RequestWizard_mv.ActiveViewIndex = 0
wPH1.Controls.Add(fPH1)
End If
End Sub
WOOT!! :D SO HAPPY!! You have no idea how much pain this saves me :P
Note: I've noticed it doesn't maintain state very well, but super easy fix compared to re-writing double the code >.<
At least, you can have one instance of Label in your code-behind and add it programmatically to the desired place by condition using placeholders in both places.
Also you can make a new user control, and place all the logic that covers your Label there. You will still have 2 instances of this control, but you will design your Label once.

UpdatePanel with GridView with LinkButton with Image Causes Full Postback

So this might be a fairly specific issue but I figured I'd post it since I spent hours struggling with it before I was able to determine the cause.
<asp:GridView ID="gvAttachments" DataKeyNames="UploadedID" AutoGenerateColumns="false" OnSelectedIndexChanged="gvAttachments_SelectedIndexChanged" runat="server">
<EmptyDataTemplate>There are no attachments associated to this email template.</EmptyDataTemplate>
<Columns>
<asp:TemplateField ItemStyle-Width="100%">
<ItemTemplate>
<asp:LinkButton CommandName="Select" runat="server"><img src="/images/icons/trashcan.png" style="border: none;" /></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
In the ItemTemplate of the TemplateField of the GridView I have a LinkButton with an image inside of it. Normally I do this when I have an image with some text next to it but this time, for whatever reason, I just have the image. This causes the UpdatePanel to always do a full postback.
Instead of changing the markup, you can goto web.config and specify ClientIDMode="Auto" in the pages tag.
Reason why UpdatePanel behaving like this is because the ClientIDMode is getting generated will be too long for UpdatePanel to register. So the ClientID got truncated in middle and such control will be treated like unregistered Control.
For more information read the following:
http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode.aspx
Change the LinkButton to be an ImageButton and the problem is solved.
<asp:ImageButton ImageUrl="/images/icons/trashcan.png" Style="border: none;" CommandName="Select" runat="server" />
Above solutions also work, But There is one more thing to check. Check form tag for your page. If id attribute is missing, you will get same issue.
If you form tag is as given below (without id), you will get issue:
<form runat="server">
<!-- your page markup -->
</form>
Please add id, as given below:
<form id="form1" runat="server">
<!-- your page markup -->
</form>
You will not need to update ClientIDMode in web.config or page or control.
You will not need to change your linkbutton in markup.
You will not need to register control for asynch postback from code behind.

Scope of controls in asp.net content blocks

Just ran into some interesting problem. I've separated a panel from a asp:Content block to another. In the original asp:Content block still resides a asp:FormView with childs, which references multiple ObjectDataSources. These ObjectDataSource are defined in the same asp:Content block.
The separated panel has child controls which are using the same ObjectDataSources. However, because of the separation, these ObjectDataSources aren't accessible anymore...
Simplified situation:
<asp:Content ID="ContentsContent" ContentPlaceHolderID="ContentsContainer" runat="server">
<asp:FormView DataSourceID="FirstSource">
<asp:DropDownList DataSourceID="SecondSource" />
</asp:FormView>
<asp:ObjectDataSource ID="FirstSource" />
<asp:ObjectDataSource ID="SecondSource" />
</asp:Content>
<asp:Content ID="ModelBoxesContent" ContentPlaceHolderID="ModalBoxesContainer" runat="server">
<asp:Panel>
<asp:DropDownList DataSourceID="SecondSource" />
</asp:Panel>
</asp:Content>
I understand that the scope of this Content blocks doesn't allow it... But does anyone have a nice solution to define the same datasource at one place, but still be able to reference them in multiple Content blocks?
Thanks.
set the datasource id on page load
seconddropdownlist.DataSourceID="SecondSource" ;

ASP.NET Webforms UpdatePanel duplicate contents

I've been handed a huge Webforms project which I'm trying to understand, and I have a problem where an Update Panel is duplicating a lot of its content. The aspx code for the panel is huge, hundreds of lines long, but it basically looks like this simple example, only with lots more asp:TextBox and asp:ListBox.
<asp:UpdatePanel runat="server" ChildrenAsTriggers="true" RenderMode="Block" UpdateMode="Conditional">
<ContentTemplate>
<div><table><tbody><tr><td>
<label>Search</label><asp:TextBox ID="Search" runat="server" />
<asp:LinkButton runat="server" OnClick="find_Click" >Find</asp:LinkButton>
</td></tr></tbody></table></div>
<div id="a"><table><tbody><tr><td>
<label>Result</label><asp:TextBox ID="Result" runat="server" />
</td></tr></tbody></table></div>
</ContentTemplate>
</asp:UpdatePanel>
and code behind like this.
public void find_Click(Object sender, EventArgs e)
{
Result.Text = "oranges";
}
When you click the LinkButton, I would expect to see in the result the <div id="a"> section, but with the text 'oranges' in the TextBox. What you actually get is <div id="a"> with 'oranges', followed by the original <div id="a"> with the empty TextBox. The worst bit is that it doesn't do it in this simple example, nor even in a page that I created that had all the original asp:TextBox and asp:ListBox but filled with dummy data. Can anyone point me to any good ways of approaching this problem?
Another solution would be to make sure all HTML tags are closed inside the asp:UpdatePanel. In my case, I've got the open header tag placed in the Site.Master file (outside of UpdatePanel control) and the closing header tag inside the UpdatePanel control (on aspx page). Because of that, every time the UpdatePanel postbacks it recreates the closing header tag again causing the content to be duplicated. After I placed the closing tag into Site.Master file, everything worked beautifully.
You might have already tried this, but in the actual problem page, is it possible to remove as many server controls out of the updatepanel and just leave in offending textbox and then see what happens? I'm guessing you'll probably have to comment out alot of .cs/.vb code, which can be a pain.
Also try removing the updatepanel and see what happens.
Some serious refactoring later, it now looks like (a very bloated version of) this.
<div><table><tbody><tr><td>
<label>Search</label><asp:TextBox ID="Search" runat="server" />
<asp:LinkButton runat="server" OnClick="find_Click" >Find</asp:LinkButton>
</td></tr></tbody></table></div>
<asp:UpdatePanel runat="server" ChildrenAsTriggers="true" RenderMode="Block" UpdateMode="Conditional">
<ContentTemplate>
<div id="a"><table><tbody><tr><td>
<label>Result</label><asp:TextBox ID="Result" runat="server" />
</td></tr></tbody></table></div>
</ContentTemplate>
</asp:UpdatePanel>

Resources