As the title says I am experiencing a problem where the SelectedIndexChanged Event of a drop down list will not fire under any circumstances. I have spent several hours looking for the solution and trying different things. Some places suggest that this is a known bug and provide work-arounds but none of them have worked for me up until this point.
The drop down in question is built here:
<tr>
<td>
Select Project
</td>
<td>
<asp:DropDownList ID="ddlProjects" runat="server"
OnSelectedIndexChanged="ddlProjects_SelectedIndexChanged" AutoPostBack="true">
</asp:DropDownList>
</td>
</tr>
This seems standard enough to me so I do not know where it could be going wrong.
EDIT (sorry I am new to this):
Code Behind:
protected void ddlProjects_SelectedIndexChanged(object sender, EventArgs e)
{
List<DashBoardImport> selectedProject = DBI.GetProject(Convert.ToInt32(ddlProjects.SelectedValue));
foreach (var proj in selectedProject)
{
txtProjectName.Text = proj.ProjectName;
this.ddlStatus.SelectedIndex = proj.Status.Equals("Current") ? 0 : 1;
var priority = proj.Priority.PriorityName;
if (priority.Equals("Low"))
{
ddlPriority.SelectedIndex = 0;
}
else if (priority.Equals("Medium"))
{
ddlPriority.SelectedIndex = 1;
}
else if (priority.Equals("High"))
{
ddlPriority.SelectedIndex = 2;
}
//txtRank.Text = proj.ProjectRank.ToString();
txtBusinessArea.Text = proj.BusinessArea.BusinessAreaName;
txtRequester.Text = proj.Requestor;
}
//selectedIndex.Value = ddlProjects.SelectedIndex.ToString();
}
There is no javascript even touching this function in anyway. I have removed it to try and take things back to basics so to speak. I have put break points in the page_load in the onselectedindexchanged function and in several other places and the event is never fired and the selected index is never changed from 0.
Edit2:
Here is the code several people have asked for.
<%# Page Title="Future Projects" Language="C#" MasterPageFile="~/Site.Master" EnableEventValidation="true"
AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="ITDashBoard.Web.Default" %>
Add AutoEventWireup="true" to your page in given below line like this
<%# Page Language="C#" AutoEventWireup="true" .................. %>
Edited: then add your own event handler
ddlPojects.SelectedIndexChanged += new EventHandler(ddlPojects_SelectedIndexChanged);
Your code behind and the .aspx code looks fine. What I suspect is a namespace issue.
Can you post up your page directive (this bit in your aspx page <%# Page Language="C#" .....). Specifically I want to see the inherits attribute. I also need to the the namespace of the .cs class where protected void ddlProjects_SelectedIndexChanged(object sender, EventArgs e) resides.
Have you also tried adding a break point in the ddlProjects_SelectedIndexChanged to see if it get hit?
Related
I'm looking to execute code in my code behind on my Masterpage, and use it on the .aspx page of child pages like Default.aspx, without having to call it through the Default.aspx.cs page.
This is my attempt by accessing it like so <% MasterPage.getPlanCost() %>, however, this does not work. As there's "no definition" for getPlanCost()
Master Page code behind:
public string getPlanCost()
{
var country = getCountry();
string gbp = "£5.99";
string euro = "€6.99";
string usd = "$8.99";
var currencyCost = usd;
if (country == "United Kingdom") // gbp
{
currencyCost = gbp;
}
else if (country == "United States" || country == "Canada" || country == "Australia" || country == "New Zealand") // usd
{
currencyCost = usd;
}
else // euro
{
currencyCost = euro;
}
return currencyCost;
}
Default.aspx page:
<p class="text-center under-title text-muted"><%=MasterPage.getPlanCost() %> Cancel Anytime.</p>
What is the quickest / most efficient way of achieving this? Furthermore, I have tried to use alternate methods seen on StackOverflow, using get and set however I was unable to get this working. Fairly new to C# so I apologise.
Although you have found a workaround, it is possible to access master page methods from child web forms, useful in cases where want your child page to affect the master page in some way. You can do this through the Page.Master property, but you will first have to register the type or cast it.
Method 1: Registering Master Type
Web Form:
<%# Page Language="C#" MasterPageFile="~/Example.Master" ... %>
<%# MasterType VirtualPath="~/Example.Master" %>
Code Behind:
Page.Master.getPlanCost();
Method 2: Casting Master Property
Code Behind:
((Example)Page.Master).getPlanCost();
To anybody wondering, I created a class called Utilities.cs
Then called it directly from here from my Default.aspx page instead.
<%=Utilities.getPlanCost()%>
I'd also like to thank #Joel Coehoorn for his comments which got me halfway there.
I have created a user control as FormPicker.ascx. I included it to AdmissionPicker.aspx page using the below code segment.
<%# Register Src="~/Common/Controls/FormPicker.ascx" TagName="FormPicker"
TagPrefix="uc1" %>
<div>
<uc1:FormPicker ID="FormPicker" Width="100%"
runat="server" AddAny="True" />
</div>
Inside FormPicker.ascx.cs I am calling the below function. LoadAdmissionData() is implemented in AdmissionPicker.aspx.cs
var admitCtrl = new AdmissionPicker();
admitCtrl.LoadAdmissionData();
LoadAdmissionData() method contains a drop down list. Drop down list is implemented in AdmissionPicker.aspx.
public void LoadAdmissionData()
{
int val=DropDownList.SelectedIndex();
}
I am using LoadAdmissionData() method in the same page and now I need to call it from FormPicker.ascx.cs. When calling it it does not identify the DropDownList. How to resolve this issue.
hi can u please change this line
var admitCtrl = new AdmissionPicker();
to
var admitCtrl = (AdmissionPicker) Page;
I have been searching the internet and most I find resolves the issue of accessing the master page properties from the user control's code behind. But I am unable to find a solution where the user control can have access to the master page's properties within the markup.
Background:
The master page dynamically adds user control onto the page.
The master page has two properties which the user control needs to access via markup.
Here is some code to represent my problem:
Master page's code behind properties:
public IModule Module
{
get
{
return MyContext.Current.Module;
}
}
public IDictionary<string, object> Arguments
{
get
{
return MyContext.Current.Arguments;
}
}
Master page dynamically adds to control in code behind (it HAS to be dynamically added in master page's code behind):
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (!(Page is VehicleForm) && !(Page is VsrManageForm) && !(Page is VpbManageForm))
{
MenuTab view = (MenuTab)this.LoadView(plhMenu, "~/Controls/MenuTab.ascx", "", MyContext.Current.Module);
}
}
User control's markup:
<web:FlowLink class="tools__lnk" arguments="<%# Arguments %>" id="flowLink1" runat="server" contextmodule='<%# Module %>' flowcall="FavouritesView" title="" rel="nofollow" ClientIDMode="Omitted">Shortlist</web:FlowLink>
<web:FlowLink class="tools__lnk" arguments="<%# Arguments %>" id="flowLink2" runat="server" contextmodule='<%# Module %>' flowcall="CompareView" title="" rel="nofollow" ClientIDMode="Omitted">Compare</web:FlowLink>
<web:FlowLink class="tools__lnk" arguments="<%# Arguments %>" id="flowLink5" runat="server" contextmodule='<%# Module %>' flowcall="UserView" title="" rel="nofollow" ClientIDMode="Omitted">Account</web:FlowLink>
Error:
Compiler Error Message: CS0103: The name 'Arguments' does not exist in the current context
Question:
How do I access <%# Arguments %> and <%# Module %> master page properties from the user control?
It might be possbile (have not tested it though) to do something like this:
arguments="<%# ((MasterPageType)this.Page.Master).Arguments %>"
Although it does not look right. You might want to redesign the way you control gets the data. Or atthe very least do the same somewhere in code behind and verify whether a current masterpage is of an expected type.
Update. The final solution that OP used incorporated ideas above, and resulted in having properties like below declared in the control:
public IDictionary<string, object> Arguments
{
get
{
MasterPageType master = this.Page.Master as MasterPageType;
if (master != null)
{
return master.Arguments;
}
else
{
return null;
}
}
}
I'm getting "Object reference not set to an instance of an object" exception, on the next line of code:
((HyperLink)Page.FindControl(id)).Visible = false;
What can be the problem?
Here is a sample from my code:
.aspx:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile="FriendsList.aspx.cs" Inherits="Private_User_Social_FriendsList" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" Runat="Server">
</asp:Content>
<div class="FriendsProposal" runat="server">
<div class="FriendsProposal_Header">FriendsP</div>
<div id="FriendsProposalPH" class="FriendsProposalPH" runat="server"></div>
.aspx.cs:
public partial class Private_User_Social_FriendsList : System.Web.UI.Page
{
DBservices DBS = new DBservices();
protected void Page_Load(object sender, EventArgs e)
List<Friends> ListFriendsProposal = DBS.getFriendsProposal(User.Identity.Name.ToString());
foreach (Friends FRIndex in ListFriendsProposal)
{
string _FriendsOutput = FR_output(FRIndex);
HyperLink tempHL = new HyperLink();
tempHL.Text = _FriendsOutput;
tempHL.CssClass = "HyperLinkFriends";
tempHL.ID = FRIndex.UdName;
FriendsProposalPH.Controls.Add(new LiteralControl("<div style='height:32px' runat='server' >"));
FriendsProposalPH.Controls.Add(tempHL);
Button tempApprove = new Button();
tempApprove.Text = "Approve";
tempApprove.Click += new EventHandler(cmdUpdate_Click);
tempApprove.ID = FRIndex.UdName + "1";
FriendsProposalPH.Controls.Add(tempApprove);
FriendsProposalPH.Controls.Add(new LiteralControl("</div>"));
}
}
private void cmdUpdate_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
string _tempID = btn.ID;
string id = _tempID.Substring(0, _tempID.LastIndexOf('1'));
DBS.ApproveFriend(User.Identity.Name.ToString(), id);
btn.Visible = false;
((HyperLink)Page.FindControl(id)).Visible = false;
}
Since you're adding the hyperlink to the FriendsProposalPH naming container (which is a placeholder control I presume) rather than the Page naming container, you should invoke the search method on that naming container and not the page itself (this method only searches within current naming container).
Judging by the code you provided the hyperlink is always added alongside the button, so perhaps the easiest way to access the right naming container and find and hide the hyperlink control is this:
btn.NamingContainer.FindControl(id).Visible = false;
your control that you are trying to find must have a runat="server" attribute or the exact same exception u receive is thrown.
dont forget that asp.net is request-response system, you cant access from the server a client-side controls.
if a control is not running at server, you cannot change it after client received it to his browser.
What I would like to do, is be able to pass two attributes to a user control, a ListName and a Permission, like so:
<uc:check id="uc" List="Shared Documents" Permission="OpenItems" runat="server">
<!-- have some HTML content here that is rendered if the permission is true -->
</uc:check>
Then in the actual check user control, have something similar to:
<%# Control language="C#" ClassName="check" %>
<%
// determine permission magic placeholder
if (DoesUserHavePermissions(perm))
{
// render nested HTML content
}
else
{
// abort rendering as to not show nested HTML content
}
%>
I have read the page on creating a templated control on MSDN, and while that would work - it really seems to be a bit overkill for what I am trying to do. Is there a control that already renders content based on a boolean expression or a simpler template example?
http://msdn.microsoft.com/en-us/library/36574bf6.aspx
Update:
The following code can be used in the ascx to model a very simple version of this:
<%# Control Language="C#" ClassName="PermissionCheck" %>
<%# Import Namespace="System.ComponentModel" %>
<script runat="server">
void Page_Init()
{
if (Allowed != null)
{
Panel container = new Panel();
Allowed.InstantiateIn(container);
PermissionBasedMessage.Controls.Add(container);
}
}
[PersistenceMode(PersistenceMode.InnerProperty)]
public ITemplate Allowed { get; set; }
</script>
<asp:Placeholder runat="server" ID="PermissionBasedMessage" />
Note: I oversimplified the check in the Page_Init method for this sample code. Additional logic checks can be added as needed.
And reference it in the calling HTML page:
<%# Register src="PermissionCheck.ascx" tagname="PermissionCheck" tagprefix="uc1" %>
<uc1:PermissionCheck ID="PermissionCheck1" runat="server">
<Allowed>Allowed Access</Allowed>
</uc1:PermissionCheck>
You could create a custom control instead of a user control: derive from the asp.net panel, add your two properties, then only render the control if the user has the required permission. E.g. something like this:
The control (put this in App_Code for example):
namespace MyControls
{
public class MyPanel : Panel
{
public string Permission { get; set; }
public string List { get; set; }
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
if (UserHasPermission()) base.Render(writer);
}
}
}
Using the control:
<%# Page ... %>
<%# Register Namespace="MyControls" TagPrefix="mc" %>
<html>
...
<mc:MyPanel runat="server" List="Shared Documents" Permission="OpenItems">
put content and/or other controls here
</mc:MyPanel>
...
Why don't you extend the LiteralControl, add properties for your settings, then render html to the .Value of the LieralControl? Seems pretty simple and a lot less of a headache than using Templated controls
The other answers are good for the generic form of your question, but for checking permissions SPSecurityTrimmedControl might do what you need.
Wrap your content with a place holder control and set the control's visibility to true or false (controls that have .Visible = false won't render any html)
<asp:PlaceHolder id="phWrapper" runat="server">
...
</asp:PlaceHolder>
Then in your code-behind set phWrapper.Visible = DoesUserHavePermissions(perm);
Hope that helps!