I have this code below. I just want to call/use the dropdown list but it is inside a item template. As I run the code, I encountered an error. Please help me.
<EditItemTemplate>
<asp:DropDownList ID="statusDDL" runat="server" AutoPostBack="True"
onselectedindexchanged="statusDDL_SelectedIndexChanged">
</asp:DropDownList>
</EditItemTemplate>
protected void statusDDL_SelectedIndexChanged(object sender, EventArgs e)
{
DropDownList ddlStatus = new DropDownList();
ddlStatus = auditGridView.FindControl("statusDDL") as DropDownList;
if (ddlStatus.SelectedItem.Text == "Closed")
{
//do logic here
}
}
Im encountering an error: object reference not set to an instance of the object. WHY? I already declared the dropdown list as shown in the code above.
You can use the sender in the SelectedIndexChanged event handler:
protected void statusDDL_SelectedIndexChanged(object sender, EventArgs e)
{
if ((sender as DropDownList).SelectedItem.Text == "Closed")
{
//do logic here
}
}
However, this is rather Winform style programming. Using WPF you should really look into data binding. But as you are using asp:DropDownList I'm not sure it's WPF?
Related
I have GridView to display data as Label
<ItemTemplate>
<asp:Label ID="lblIsActive" runat="server" Text='<%# GetIcon((String)Eval("IS_ACTIVE"))%>' SkinID='<%# GetSkinId((String)Eval("IS_ACTIVE"))%>' />
</ItemTemplate>
c#
protected string GetSkinId(string name)
{
if (name == "Y")
{
return "sknActive";
}
else
return "sknInactive";
}
but I get error I can't set SkinID Programmatically, any idea how I can allow SkinID in code behind?
Updated
I decide to not make SkinID, so I'm doing this
<ItemTemplate>
<asp:Label ID="lblIsActive" runat="server" Text='<%# GetIcon((String)Eval("IS_ACTIVE"))%>'
ForeColor='<%# GetColor((String)Eval("IS_ACTIVE"))%>' />
</ItemTemplate>
And my function on c# to get color
protected string GetColor(string name)
{
if (name == "Y")
{
return "#99099";
}
else
return "#03211";
}
I get error that
string can not convert to System.Drawing
The error message is self explanatory. Based on the data source you have the control in your gridview is dynamically getting created and after this it is trying to set the SkinId property and thus the error.
You can achieve this when the row is getting created in your gridview. Yes you can use the RowCreated event of gridvew like this:-
protected void GridView1_RowCreated(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lblIsActive = e.Row.FindControl("lblIsActive") as Label;
if(lblIsActive.Text == "Y")
lblIsActive.SkinID = "sknActive";
else
lblIsActive.SkinID = "sknInactive";
}
}
Please note that this won't work in RowDataBound event since this event is fired after the row is created and when a data row is bound to data.
Update:
First of all your assumption is wrong that we are looping actually we are not. We are simply handling the event which is raised by the gridview control. Anyways since now you have changed your mind and switched to ForeColor approach the problem with your code is that the ForeColor property expects a System.Drawin.Color enum but your passing a string thus the error. For correctint you will have to return Color instead of string like this:-
protected Color GetColor(string name)
{
if (name == "Y")
return Color.Red;
else
return Color.Green;
}
Here I am returning sample colors but you need to replace them with actual intended colors. If you just have the hex string and not sure about the Color enum value then you can use the method mentioned in this answer to do so.
The error message tells you what you need to do: move the initializing of the SkinID property to the Page_PreInit stage of the page lifecycle.
Basically, this entails adding the following event handler to your code behind:
protected void Page_PreInit(object sender, EventArgs e)
{
lblIsActive.SkinId = GetSkinID(IS_ACTIVE); // no need for eval here
}
I have a text box and a RadComboBox like this :
<asp:TextBox ID="txt_inner_emp_num" runat="server" Width="60px"
ontextchanged="txt_inner_emp_num_TextChanged" AutoPostBack="true"></asp:TextBox>
<telerik:RadComboBox ID="rad_ddl_inner_emp_name" runat="server" CausesValidation="False"
CollapseDelay="0" Culture="ar-EG" ExpandDelay="0" Filter="Contains" ItemsPerRequest="100"
MarkFirstMatch="true" Width="380px" EnableAutomaticLoadOnDemand="True" EmptyMessage="-emp name-" ShowMoreResultsBox="True" AutoPostBack="True">
</telerik:RadComboBox>
According to the Telerik Documentation
Set a data source to the RadComboBox. Use either DataSourceID or the
DataSource property to do this and set the DataTextField and
DataValueField properties to the respective fields in the data source.
(Note that when using DataSource you must set the property on each
postback, most conveniently in Page_Init.) Set
EnableAutomaticLoadOnDemand to true.
protected void BindEmployees()
{
rad_ddl_inner_emp_name.Items.Clear();
rad_ddl_inner_emp_name.DataSource = Utilities.GetAllEmployees();
rad_ddl_inner_emp_name.DataTextField = "name";
rad_ddl_inner_emp_name.DataValueField = "emp_num";
rad_ddl_inner_emp_name.DataBind();
}
protected void Page_Init(object sender, EventArgs e)
{
BindEmployees();
}
protected void txt_inner_emp_num_TextChanged(object sender, EventArgs e)
{
rad_ddl_inner_emp_name.ClearSelection();
rad_ddl_inner_emp_name.Items.FindItemByValue(txt_inner_emp_num.Text.TrimEnd()).Selected = true;//Get exception here Object reference not set to an instance of an object.
}
I find rad_ddl_inner_emp_name.Items.Count = 0 !! before set the selection ! How to fix this problem ?
As I'm sure you aware of by now, the radcombox typeahead functionality searches text via client side interaction and not by value, which is why you can't find the values.
What I would suggest is having a secondary object to search by emp_num (assuming that's the value that will always be entered into the textbox).
For example, create a global variable:
private Dictionary<string, string> Emp_Dict = new Dictionary<string, string>();
Then populate this dictionary when you do your binding. The following code assumes an ienumerable type being returned. If not you may have to populate the dictionary differently. Also, for this to work, you have to include (System.Linq).
var dataSource = Utilities.GetAllEmployees();
Emp_Dict = dataSource.ToDictionary(ex => ex.emp_num, ex => ex.name);
rad_ddl_inner_emp_name.Items.Clear();
rad_ddl_inner_emp_name.DataSource = dataSource;
rad_ddl_inner_emp_name.DataTextField = "name";
rad_ddl_inner_emp_name.DataValueField = "emp_num";
rad_ddl_inner_emp_name.DataBind();
So now we need to use the dictionary on the text changed event.
protected void txt_inner_emp_num_TextChanged(object sender, EventArgs e)
{
rad_ddl_inner_emp_name.ClearSelection();
if (Emp_Dict.ContainsKey(txt_inner_emp_num.Text.TrimEnd()))
{
rad_ddl_inner_emp_name.SelectedValue = txt_inner_emp_num.Text.TrimEnd();
rad_ddl_inner_emp_name.Text = Emp_Dict[txt_inner_emp_num.Text.TrimEnd()];
}
}
Now when the text changes in the text box, the radcombobox will update when a valid emp_num is entered into the textbox.
The Problem is that the Items only get loaded when you request them!
Set
EnableAutomaticLoadOnDemand="False"
and it will work!
UPDATE:
if you want to use LoadOnDemand set these two Properties and delete the EnableAutomicLoadOnDemand!
EnableLoadOnDemand="True"
EnableItemCaching="True"
UPDATE 2:
Enable ItemCaching isn´t necessary, but it doesn´t hurt!
You do not need to bind data to RadComboBox on every postback unless you disable the view state.
Filter, MarkFirstMatch and EnableAutomaticLoadOnDemand are not useful in your case as you are loading all employees by yourself.
LoadOnDemand basically is when user starts typing inside ComboBox, ComboBox fires ItemsRequested event and retrieves data via ajax.
<asp:TextBox ID="txt_inner_emp_num" runat="server" Width="60px"
ontextchanged="txt_inner_emp_num_TextChanged" AutoPostBack="true" />
<telerik:RadComboBox ID="rad_ddl_inner_emp_name" runat="server"
CausesValidation="False" Culture="ar-EG">
</telerik:RadComboBox>
protected void Page_Init(object sender, EventArgs e)
{
if (!IsPostBack)
{
rad_ddl_inner_emp_name.DataSource = Utilities.GetAllEmployees();
rad_ddl_inner_emp_name.DataTextField = "name";
rad_ddl_inner_emp_name.DataValueField = "emp_num";
rad_ddl_inner_emp_name.DataBind();
}
}
protected void txt_inner_emp_num_TextChanged(object sender, EventArgs e)
{
string value = txt_inner_emp_num.Text;
if(!string.IsNullOrWhiteSpace(value))
{
value = value.Trim();
if (rad_ddl_inner_emp_name.Items
.FindItemByValue(txt_inner_emp_num.Text.Trim()) != null)
rad_ddl_inner_emp_name.SelectedValue = value;
}
}
Since you don't have any item in rad_ddl_inner_emp_name.Items you can set txt_inner_emp_num.Text as selected in ddl.
First check if rad_ddl_inner_emp_name.Items count > 0 then set desired text selected. Or you can check if rad_ddl_inner_emp_name.Items.FindItemByValue(txt_inner_emp_num.Text.TrimEnd()) is not null.
I have a gridview add a link button "Edit":
<asp:LinkButton ID="btnViewDetails" runat="server" text="Edit" CommandName="Select"></asp:LinkButton>
and
protected void GridView1_SelectedIndexChanged(object sender, EventArgs e)
{
using (var dataContext = new NewsStandAloneDataContext(Config.StandaloneNewsConnectionString))
{
DetailsView1.ChangeMode(DetailsViewMode.Edit);
DetailsView1.Visible = true;
var dataList =
dataContext.sp_Name(Convert.ToInt32(GridView1.SelectedValue), Value1);
ScriptManager.RegisterStartupScript(this, GetType(), "show1", "openEditWindow();", true);
DetailsView1.DataSource = dataList;
DetailsView1.DataBind();
}
}
But my details view does not show anything.
Looking at your code you have two different methods in play. In your ViewDetails button you are referencing a command name and argument. In your other block of code you are responding to the changing of the selected row. Two different concepts.
You would want to show the details view from the "ItemCommand" event, and not the selectedindexchanged event.
So I have a country dropdownlist and a state dropdownlist which is being populated dynamically based off of the country chosen. When I click the country the state dropdown gets populated just fine but the problem arises when I click a value (state) from the other dropdown, the list instead of retaining the selected item will go back to the first item of the list and no selectedvalue are displayed.
<td><asp:DropDownList ID="ddlState" runat="server"
DataSourceId="dsStateList"
DataTextField="state_nm"
DataValueField="state_cd"
OnSelectedIndexChanged="ddlState_SelectedIndexChanged"
AutoPostBack="true"
AppendDataBoundItems="true"
Width="160px" OnDataBound="ddlState_OnDataBound">
</asp:DropDownList>
</td>
<asp:DropDownList ID="ddlCountry" runat="server"
DataSourceId="dsCountryList"
DataTextField="COUNTRY_NAME"
DataValueField="COUNTRY_CIA_ID"
OnSelectedIndexChanged="ddlCountry_SelectedIndexChanged"
OnDataBound="ddlCountry_OnDataBound"
AutoPostBack="true"
AppendDataBoundItems="true"
Width="160px">
</asp:DropDownList>
protected void ddlState_SelectedIndexChanged(object sender, EventArgs e)
{
string comboStateCODE = ddlState.SelectedValue;
dsCompanyListParam.Text = comboStateCODE;
ddlCountry.DataBind();
ddlState.DataBind();
}
protected void ddlState_OnDataBound(object sender, EventArgs e)
{
ddlState.Items.Insert(0, "Please Select a State");
}
protected void ddlCountry_SelectedIndexChanged(object sender, EventArgs e)
{
ddlState.Items.Clear();
dsStateList.SelectParameters["iCountryID"].DefaultValue = ddlCountry.SelectedValue;
dsCompanyListParam.Text = ddlCountry.SelectedValue;
Trace.Warn("ddlCountry_SelectedIndexChanged");
ddlCountry.DataBind();
ddlState.DataBind();
}
protected void ddlCountry_OnDataBound(object sender, EventArgs e)
{
ddlCountry.Items.Insert(0, "Please Select a Country");
}
I presume that somewhere in your Page_Load() you are making a call to a method that populates the dropdown... you need to encapsulate this into an IF !PostBack block:
// somewhere in PageLoad()...
If(!IsPostBack)
{
PopulateDropdown();
}
Using the convention above, the dropdown will only be populated on the first ever page load. What I suspect is happening is that when you make a selection from the other dropdown, the AutoPostBack is executing the Page_Load() method (as it should) and repopulating the dropdowns again.
Using the convention above should help avoid this.
Your state drop down is set to Autopostback - is it possible that your code to populate the country drop down is executing again on postback, thus rendering the selected state invalid because the country dropdown was repopulated
I would remove the ddlCountry.DataBind(); from the ddlState_SelectedIndexChanged event. I don't see why you need to do another DataBind there.
Solved it!
Ok, just so anyone who's stuck with a similar problem and can't find any other areas to look at here's how I fixed the stupid problem.
First of all, I was using a stored procedure and the stored procedure is concatenating the values from two fields. I set the parameters the Integer(4) which I didn't noticed there're a couple of countries with codes of more than 4. So basically, it's returning a NULL selectedvalue which in turn will not generate any value since my onselectedindexchanged method is based off of the selectedvalue and for some reason a NULL is not being processed.
So yeah, check your stored procs and parameter data! :D
Thanks for your time!
I have to set a LinkButton's OnClientClick attribute but I don't know what this value is until the LinkButton is bound to. I'm trying to set the value when the repeater binds, but I can't workout how to get the 'boundItem/dataContext' value...
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:LinkButton Text="HelloWorld" ID="Hyper1" runat="server" OnDataBinding="Repeater1_DataBinding" >
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
protected void Page_Load(object sender, EventArgs e)
{
var list = new List<TestObject>();
list.Add(new TestObject() {TestValue = "testing1"});
list.Add(new TestObject() { TestValue = "testing2" });
list.Add(new TestObject() { TestValue = "testing3" });
this.Repeater1.DataSource = list;
this.Repeater1.DataBind();
}
public void Repeater1_DataBinding(object sender, EventArgs e)
{
var link = sender as HyperLink;
//link.DataItem ???
}
Is there anyway to find out what the current rows bound item is?
Maybe you need to use ItemDataBound event. It provides RepeaterItemEventArgs argument which has DataItem available
this.Repeater1.ItemDataBound += Repeater1_ItemDataBound;
void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
var dataItem = e.Item.DataItem;
}
I assume you are trying to get the value for the row that is currently being databound?
You can change your function to:
public void Repeater1_DataBinding(object sender, EventArgs e)
{
var link = sender as HyperLink;
string valueYouWant = Eval("TestValue").ToString();
// You could then assign the HyperLink control to whatever you need
link.Target = string.Format("yourpage.aspx?id={0}", valueYouWant);
}
valueYouWant now has the value of the field TestValue for the current row that is being databound. Using the DataBinding event is the best way to do this compared to the ItemDataBound because you don't have to search for a control and localize the code specifically to a control instead of a whole template.
The MSDN library had this as a sample event handler:
public void BindData(object sender, EventArgs e)
{
Literal l = (Literal) sender;
DataGridItem container = (DataGridItem) l.NamingContainer;
l.Text = ((DataRowView) container.DataItem)[column].ToString();
}
(see http://msdn.microsoft.com/en-us/library/system.web.ui.control.databinding.aspx)
As you can see it is a simple demonstration of how to access the data item and get data from it. Adapting this to your scenario is an exercise left to the reader. :)