Render asp:menuitems as links - c#

I have a asp:menu define like so:
<div id="MenuContainer" runat="server" class="menuContainer">
<asp:Menu ID="DefaultMenu" runat="server" DataSourceID="SiteMapDataSource" SkinID="TopMenu" OnMenuItemDataBound="DefaultMenu_MenuItemDataBound" OnMenuItemClick="DefaultMenu_MenuItemClick" DynamicPopOutImageTextFormatString="" >
<DataBindings>
<asp:MenuItemBinding DataMember="SiteMapNode" NavigateUrlField="Url" TextField="Title" ToolTipField="Description" />
</DataBindings>
</asp:Menu>
<asp:SiteMapDataSource ID="SiteMapDataSource" runat="server" EnableViewState="False" ShowStartingNode="False" SiteMapProvider="WebserviceSiteMapProvider" />
</div>
The menu items are generated from a SiteMapDataSource as seen above. When rendered all the menu links are postbacks which then redirect to the relevant page:
protected void DefaultMenu_MenuItemClick(object sender, MenuEventArgs e)
{
Response.Redirect(e.Item.DataPath);
}
Anyone know any easy way to render the menu items as hyper links rather than postbacks?
I ask as this is adding an unnecessary round-trip to my application which on a specific customer set-up is causing performance issues. I've been searching around on the internet all morning for this and can't really see any obvious.
Note: This is .Net 3.5 that is being used.
If I'm missing something please just say.
Nevermind, one of my colleagues showed me the issue, the sitemapdatasource was not returning a url therefore the links where being rendered as postbacks rather than hyperlinks.

Is it necessary to use:
OnMenuItemClick="DefaultMenu_MenuItemClick"
that will create a postback, you need to build a control without it.
Here is a link to an answer with a simpler usage of menu for a sitemap, it might be worth a look.
https://stackoverflow.com/a/1030609/2366880

Related

Adding Div dynamically to my web page as per the contents in the table using ASP.Net

I want to display every individual record from table on my web page, if the records in table increases the number of div should also increase.
How do i achieve this using ASP.net.
Please if any one can guide me as i am new to ASP.Net
Thank you in advance
As stated earlier using MVC would be a nice approach but u will have to learn a bit to use it.
As per the current scenario you can use repeaters which are exactly designed for what you want to accomplish.
assuming your database looks something similar to this..
id int primary key
name nvarchar(50)
etc...
//suppose you have your database data in "dataFromDatabase"
now in your asp.net page just define a repeater like this
<div id="content">
<asp:repeater id="repeaterData" runat="server">
<HeaderTemplate>
<Table>
<tr>
<th>Id:</th>
<th>Name : </th>
</tr>
</HeaderTemplate>
<ItemTemplate>
<td><%#Eval("id")%></td>
<td><%#Eval("name")%></td>
</ItemTemplate>
<FooterTemplate>
</Table>
</FooterTemplate>
</repeater>
</div>
and in your .aspx.cs page
bind the repeater with your datasource
repeaterData.DataSource = dataFromDatabase
repeaterData.DataBind();
thats all you need to do to get it up and running...
and using GridView would be even more simpler you just need to drag that from ToolBox to your aspx file and select your data Source visually and violla you are done... no coding required.....
although you will have to do some coding for the edit, delete and some fancy stuff...
Hope it helps.
It sounds like you're looking to implement a repeater class.
EDIT
Here is some sample code per your request from the link mentioned above:
<asp:Repeater
DataMember="string"
DataSource="string"
DataSourceID="string"
EnableTheming="True|False"
EnableViewState="True|False"
ID="string"
OnDataBinding="DataBinding event handler"
OnDisposed="Disposed event handler"
OnInit="Init event handler"
OnItemCommand="ItemCommand event handler"
OnItemCreated="ItemCreated event handler"
OnItemDataBound="ItemDataBound event handler"
OnLoad="Load event handler"
OnPreRender="PreRender event handler"
OnUnload="Unload event handler"
runat="server"
Visible="True|False"
>
<AlternatingItemTemplate>
<!-- child controls -->
</AlternatingItemTemplate>
<FooterTemplate>
<!-- child controls -->
</FooterTemplate>
<HeaderTemplate>
<!-- child controls -->
</HeaderTemplate>
<ItemTemplate>
<!-- child controls -->
</ItemTemplate>
<SeparatorTemplate>
<!-- child controls -->
</SeparatorTemplate>
</asp:Repeater>
You can use gridview or repeater to solve your.
Gridview basic example
http://www.codeproject.com/Articles/23471/Editable-GridView-in-ASP-NET-2-0
Repeater basic example
http://www.w3schools.com/aspnet/aspnet_repeater.asp
If you're completely new to ASP.NET, I'd suggest working with the ASP.NET MVC Framework instead of with WebForms. Ultimately it's a matter of taste, but the MVC framework has been designed with the deliberate goal of making it easy to write good quality code, so if you're starting fresh anyway you might as well learn to do it well from the beginning.
The best place to start is probably at the official site of ASP.NET MVC. They have a good "getting started"-guide, and lots and lots of tutorials on levels from absolute beginner to advanced web developing.
And a side note to all the WebForms fans out there: I'm definitely not saying you can't write good quality code with WebForms - however, if you look around the internet most examples you find are poorly constructed and full of antipatterns. Starting with ASP.NET MVC Framework yields a higher chance of the web resources you find demonstrating good practices, rather than quick hacks.
or:
for(int i= 0;i<10i++){
label.text="<div>"+something+"</div>"+label.text
}

What am I doing wrong in this ASPxPageControl? (dev express)

Here is what I have. I am trying to use Developer Express ASPxPageControl. I want to only load the first TabPage (and WebUserControl it contains) when the page is loaded and then when I click on subsequent tabs, load those WebUserControls. I have found documentation here and other places telling me to
set the ASPxPageControl.AutoPostBack property to false, and ASPxPageControl.EnableCallBacks set to true
However, this is not working for me. I have verified with the debugger that when the main page is loaded, each of my WebUserControls are also loading. Am I misunderstanding the idea of the ASPxPageControl??
<dxtc:ASPxPageControl ID="ASPxPageControl1" runat="server" ActiveTabIndex="0"
EnableCallBacks="True"
AutoPostBack="false" >
<TabPages>
<dxtc:TabPage Text="Detail" Name="tabDetail">
<ContentCollection>
<dxw:ContentControl ID="ContentControl3" runat="server">
<uc13:WUCDetail ID="WUCDetail" runat="server" />
</dxw:ContentControl>
</ContentCollection>
</dxtc:TabPage>
<dxtc:TabPage Text="Room" Name="tabRoom">
<ContentCollection>
<dxw:ContentControl ID="ContentControl4" runat="server">
<uc11:WUCRoom ID="WUCRoom" runat="server" />
</dxw:ContentControl>
</ContentCollection>
</dxtc:TabPage>
<dxtc:TabPage Text="Mailers" Name="tabMailers">
<ContentCollection>
<dxw:ContentControl ID="ContentControl5" runat="server">
<uc10:WUCMailers ID="WUCMailers" runat="server" />
</dxw:ContentControl>
</ContentCollection>
</dxtc:TabPage>
</TabPages>
</dxtc:ASPxPageControl>
However, this is not working for me. I have verified with the debugger
that when the main page is loaded, each of my WebUserControls are also
loading. Am I misunderstanding the idea of the ASPxPageControl??
I'm afraid you are misunderstanding the idea of the example "How to create and load an active tab's content on a callback". The main idea of this example is to create and load an active tab's content on a callback.
But you've specified content for all pages directly in markup. Thus these controls will be created and loaded in any cases. Please, create an empty tabpages and then use the approach demonstrated in this example to create and load page's content only when active tab changed.

The right way to put querystring-style information in the location bar in asp.net

I am working on an asp.net 4.0 application. One of the site does is allow users to search for stuff in the database. The page that is done on looks like this:
<asp:Panel ID="pnlSearch" runat="server" DefaultButton="lnkSearch" cssclass="searchbar box">
<span id="searchFor"><strong>Search for</strong></span>
<asp:TextBox ID="txtSearch" runat="server"></asp:TextBox>
<asp:LinkButton ID="lnkSearch" runat="server" Text="Search" onclick="lnkSearch_Click"></asp:LinkButton>
</asp:Panel>
lnkSearch_Click performs the query on the database, then binds the results to a asp:Repeater.
This all works, but there is a problem: The URL is not changed for the user, and so there is no way for the user to save a query for later, or to link to to their friends.
I could solve this by doing something a bit like:
<script>
function doSearch() { location.href='~/defaultpro.aspx?search='+escape($('txtSearch').value);
</script>
<a ID="lnkSearch" href="javascript:void(0);" Text="Search" onclick="doSearch();" />
But this feels like going out of my way to avoid using the tools asp.net provides. Is there a better way to do this?
The best way of doing it is to have a form with method set to get:
<form method="get">
But ASP.NET requires the one huge form that wraps all the controls, so its not an option for you.
Other way you can implement this, is to create an event handler for click event of your Search button:
protected void SearchButton_Click(object sender, EventArgs e){
Response.Redirect(Request.RawUrl + "?search=" + Server.UrlEncode(txtSearch.Text));
}
And bind all the data in the PageLoad event
If you are using .Net 4.0 why are you not using URL Routing?
I wrote this article explaining how to use the new feature.
So you would have a click event that performs your search and then at the end of the search (logic code) you can keep their search in the URL by using URL Routing.
Another method you could use is Sessions. I would not suggest cookies as they are on the client and prone to manipulation. One last option you could use is Context.
If you are going from one page directly to the next you could use page history.

Launch modaldialog from server-side

I have created 2 modaldialogs. My problem is that I need to show them from server-side if a few conditions are met (after clicking a button). I've been googling around and there was a solution to add the extender to an invisible control and launch it from code.
But since there's nothing showing, I suppose I'm doing something wrong. I tried it with a click on the linkbutton, to see if that was working and this is showing the dialog.
Thanks in advance.
Markup:
<asp:LinkButton ID="lnkPrompts" runat="server">LinkButton</asp:LinkButton>
<asp:ModalPopupExtender ID="lnkPrompts_ModalPopupExtender" runat="server"
BackgroundCssClass="modalBackground" Enabled="True"
TargetControlID="lnkPrompts" PopupControlID="pnlPromptModal"
OkControlID="pnlPromptModal">
</asp:ModalPopupExtender>
<asp:Panel ID="pnlPromptModal" runat="server" Width="350px" Height="70px"
CssClass="modalPopup" Style="display: none;">
Some text
<div style="">
<asp:Button ID="btnModalPromptOk" runat="server" Text="OK" />
</div>
</asp:Panel>
On server-side:
protected void btnViewPrompts_Click(object sender, EventArgs e)
{
if (conditionMet)
{
Response.Redirect("IvrPrompts.aspx?Id=" + breakdownView.Id);
}
else
{
//ToDo: Show modaldialogbox
lnkPrompts_ModalPopupExtender.Show(); //This does nothing...
}
}
The times that I've used the ModalPopupExtender in the way you're describing, I've wrapped them in an UpdatePanel. This is the only way to have the server side "initiate" the action like you're describing.
Well, seems it does work. The only problem was that I had a Response.Redirect right after the line lnkPrompts_ModalPopupExtender.Show(); and that was the problem. The dialog was never shown. After commenting out the Redirect, it all works as it should.
Anyway, sorry for wasting your time. Should be more awake next time when trying something new...
You need to do this from javascript on the client side. The server can never initate actions on the client, but the client can ask the server if the condition is met and take actions based on that. The way you want to do this is probably by performing an Ajax background call from the client to the server when the button is pressed.

How to edit CSS style of a div using C# in .NET

I'm trying to grab a div's ID in the code behind (C#) and set some css on it. Can I grab it from the DOM or do I have to use some kind of control?
<div id="formSpinner">
<img src="images/spinner.gif" />
<p>Saving...</p>
</div>
Add the runat="server" attribute to it so you have:
<div id="formSpinner" runat="server">
<img src="images/spinner.gif">
<p>Saving...</p>
</div>
That way you can access the class attribute by using:
formSpinner.Attributes["class"] = "classOfYourChoice";
It's also worth mentioning that the asp:Panel control is virtually synonymous (at least as far as rendered markup is concerned) with div, so you could also do:
<asp:Panel id="formSpinner" runat="server">
<img src="images/spinner.gif">
<p>Saving...</p>
</asp:Panel>
Which then enables you to write:
formSpinner.CssClass = "classOfYourChoice";
This gives you more defined access to the property and there are others that may, or may not, be of use to you.
Make sure that your div is set to runat="server", then simply reference it in the code-behind and set the "class" attribute.
<div runat="server" id="formSpinner">
...content...
</div>
Code-behind
formSpinner.Attributes["class"] = "class-name";
This question makes me nervous. It indicates that maybe you don't understand how using server-side code will impact you're page's DOM state.
Whenever you run server-side code the entire page is rebuilt from scratch. This has several implications:
A form is submitted from the client to the web server. This is about the slowest action that a web browser can take, especially in ASP.Net where the form might be padded with extra fields (ie: ViewState). Doing it too often for trivial activities will make your app appear to be sluggish, even if everything else is nice and snappy.
It adds load to your server, in terms of bandwidth (up and down stream) and CPU/memory. Everything involved in rebuilding your page will have to happen again. If there are dynamic controls on the page, don't forget to create them.
Anything you've done to the DOM since the last request is lost, unless you remember to do it again for this request. Your page's DOM is reset.
If you can get away with it, you might want to push this down to javascript and avoid the postback. Perhaps use an XmlHttpRequest() call to trigger any server-side action you need.
Add the runat="server" attribute to the tag, then you can reference it from the codebehind.
Add runat to the element in the markup
<div id="formSpinner" runat="server">
<img src="images/spinner.gif">
<p>Saving...</p>
</div
Then you can get to the control's class attributes by using
formSpinner.Attributes("class")
It will only be a string, but you should be able to edit it.
How do you do this without runat="server"? For example, if you have a
<body runat="server" id="body1">
...and try to update it from within an Updatepanel it will never get updated.
However, if you keep it as an ordinary non-server HTML control you can. Here's the Jquery to update it:
$("#body1").addClass('modalBackground');
How do you do this in codebehind though?
If you do not want to make your control runat server in case you need the ID or simply don't want to add it to the viewstate,
<div id="formSpinner" class="<%= _css %>">
</div>
in the back-end:
protected string _css = "modalBackground";
If all you want to do is conditionally show or hide a <div>, then you could declare it as an <asp:panel > (renders to html as a div tag) and set it's .Visible property.
To expand on Peri's post & why we may not want to use viewstate the following code:
style="<%= _myCSS %>"
Protected _myCSS As String = "display: none"
Is the approach to look at if you're using AJAX, it allows for manipulating the display via asp.net back end code rather than jquery/jscript.

Categories