I want to find an unordered list inside my GridView so that I can hide it based on a condition. I do not know what to cast the object as however. Using HtmlGenericControl does not seem to work. I receive a Object reference not set to an instance of an object error.
Markup:
<asp:GridView ID="myGV" runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="myCb" runat="server" Text='Hi'/>
<ul id="myUnorderedList" runat="server" Visible="True">
<li>
<asp:TextBox ID="myTb" runat="server" Width="300" />
</li>
</ul>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
C#:
foreach (GridViewRow row in myGV.Rows)
{
if (Some Condition)
{
//works bc properly casted to CheckBox
((CheckBox) row.FindControl("myCb")).Visible = false;
//Does not work. What to cast this to?
((System.Web.UI.HtmlControls.HtmlGenericControl) row.FindControl("myUnorderedList")).Visible = false;
}
}
System.Web.UI.HtmlControls.HtmlGenericControl is a correct cast for ul.
Besides, you do not even need to cast to HtmlGenericControl, because Visible is a property of System.Web.UI.Control from which all web controls inherited.
You just need the following code -
(row.FindControl("myUnorderedList")).Visible = false;
Related
Ok I have a many to many relationship like this:
Walk = {WalkID, title, ...., (Navigation Properties) Features}
Feature = {FeatureID, featureName, description, (Navigation Properties) DogWalks}
I do of course have a junction table, but EF assumes this thus it is not shown in my edmx diagram:
WalkFeatures = {WalkID, FeatureID} //junction, both FK
So using LINQ with EF, I am now trying to grab the features for the Walk at WalkID=xx.
This is my formview:
<asp:FormView ID="FormView1" runat="server" ItemType="Walks.DAL.Walk" SelectMethod="FormView1_GetItem">
<ItemTemplate>
<h1><%# Item.Title %></h1>
...
</ItemTemplate>
</asp:FormView
<asp:Label ID="lbFeatures" runat="server" Text="Label"></asp:Label>
And selectMethod:
public Walks.DAL.Walk FormView1_GetItem([QueryString("WalkID")] int? WalkID)
{
using (WalkContext db = new WalkContext())
{
var walk = (from n in db.Walks.Include("Features")
where n.WalkID == WalkID
select n).SingleOrDefault();
foreach(var f in walk.Features){
lbFeatures.Text += f.FeatureName + "<br/>";
}
return walk;
}
}
The code runs fine, but is there a way that I can display the Walk.Features directly inside the <ItemTemplate> of the formview rather than using a label and a loop? Can the attribute be directly binded like the other properties in the .aspx page?
I have also used this new feature not that extensively but just gave it a try for this particular scenario and this is what I have:-
Simply return walk from FormView1_GetItem method and don't manipulate your label control there. Now, you can use a Repeater control to display the lbFeatures control (since it is going to repeat dynamically) like this:-
<ItemTemplate>
<h1><%# Item.Title %></h1>
<asp:Repeater ID="lbFeatures" runat="server" DataSource='<%# Item.Features%>'>
<ItemTemplate>
<asp:Label ID="lblTest" runat="server"
Text='<%# Eval("FeatureName") %>'></asp:Label>
<br />
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
As you can see I am able to assign the datasouce of repater control as Item.Features, then use the conventional approach to bind the label. This looks clean and simple :)
I have a dropdownlist that I populate from the DB, and depending on business logic I need to be able to validate the selected item (TEXT) from the dropdownlist with server side vaildation. Requirements state I cannot simply filter it out as part of the SQL statement. The solution I have been trying to get to work is to simply create a customvalidation in the code behind.
The validation is called, BUT I cannot figure out how to reference the ddl DataTextField value for the item selected. When I try and do the server side code below the asp.net system states that my dropdownlist does not exist within the detailsview and provides a red underline as a result. In this instance it will always be insertmode.
Suggestions
ASP Code
<asp:DetailsView ID="dtlSample" runat="server" AutoGenerateEditButton="true" AutoGenerateRows="false">
<Fields>
.
.
.
<asp:TemplateField HeaderText="Position">
<ItemTemplate>
<%# Eval("Age") %>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlPosition" runat="server" AutoPostBack="True"
LDataSource="Select Position, PositionId from ...." DataTextField="Position" DataValueField="PositionId"
></asp:DropDownList>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList ID="ddlPosition" runat="server" AutoPostBack="True"
LDataSource="Select Position, PositionId from ...." DataTextField="Position" DataValueField="PositionId"
></asp:DropDownList>
</InsertItemTemplate>
<asp:CustomValidator ID="cvPos" Display="Dynamic" ControlToValidate = "DDLPosition"
OnServerValidate="ddlPos_Check" runat="server" ForeColor="Red" ErrorMessage="My error message"></asp:CustomValidator>
</asp:TemplateField>
</Fields>
CODE BEHIND
protected void ddlPos_Check(object sender, ServerValidateEventArgs args)
{
if (ddPosition.SelectedItem.Text.Contains("some value")
args.IsValid = false;
else
args.IsValid = true;
}
Murphy's law, answer your own question a few hours after.
DropDownList ddlList=DetailsView2.FindControl("ddlPosition") as DropDownList;
if (ddlList != null)
{
if (ddlList.SelectedItem.Text.Contains("text")) {
args.IsValid = false;
}
else
{
args.IsValid = true;
}
}
I am doing a task related to telerik grid. In that I have added checkboxes as item templates. When I check the box and if I click on submit, that should be updated in database.
Here is the code I have tried.
aspx:
<telerik:GridTemplateColumn HeaderText="Is Active" ItemStyle-HorizontalAlign="Left" HeaderStyle-HorizontalAlign="Left">
<ItemTemplate>
<asp:CheckBox ID="chkIsActive" runat="server" AutoPostBack="true" OnCheckedChanged="chkIsActive_OnCheckedChanged" />
</ItemTemplate>
</telerik:GridTemplateColumn>
aspx.cs code:
public void chkIsActive_OnCheckedChanged(object sender,EventArgs e)
{
CheckBox chkIsActive = (CheckBox)sender;
GridViewRow Row = (GridViewRow)chkIsActive.NamingContainer;
string cid = Row.Cells[1].Text;
bool status = chkIsActive.Checked;
}
Error which I am getting:
Unable to cast object of type 'Telerik.Web.UI.GridDataItem' to type 'System.Web.UI.WebControls.GridViewRow'.
Please resolve my problem.
The problem is that you are trying to cast a telerik Telerik.Web.UI.GridDataItem to a normal gridviewrow, cast it to Telerik.Web.UI.GridDataItem instead.
Telerik.Web.UI.GridDataItem Row = (Telerik.Web.UI.GridDataItem)chkIsActive.NamingContainer;
Not really sure how to handle this issue but here goes...
I have a gridview with two checkboxes for each row, below is an example of the item template:
<ItemTemplate>
<asp:CheckBox ID="MasterCheckbox" runat="server"/>
<asp:CheckBox ID="ChildCheckbox" runat="server" />
</ItemTemplate>
I would like the 'enabled' property of the ChildCheckbox to be controlled by the 'Checked' property of the MasterCheckbox ... so in other words the ChildCheckbox is only enabled when the MasterCheckbox has been checked.
I know that I will need to append a handler onto the MasterCheckbox control to invoke some javascript to perform the necessary actions on the client-side - this will probably be done in the row_databound() method?
I can't quite figure out the javascript required to get this to work, so any hints/tips would be welcome.
Thanks
Dal
First you dont need to answer your own question,you can add comments into your very first question.
Since you are using GridView , I think you are binding something for MasterCheckBox,
so let's say that it's boolean value in a dataTable.
For Example it's a row contaning column with name IsMasterChecked
You can handle Enabling the other one with binding custom expressions as
<ItemTemplate>
<asp:CheckBox ID="MasterCheckbox" runat="server" />
<asp:CheckBox ID="ChildCheckbox" runat="server" Enabled='<%# Convert.ToBoolean(Eval("IsMasterChecked")) %>'/>
</ItemTemplate>
or
<ItemTemplate>
<asp:CheckBox ID="MasterCheckbox" runat="server" />
<asp:CheckBox ID="ChildCheckbox" runat="server" Enabled='<%# Convert.ToBoolean(Eval("IsMasterChecked")) ? "true" : "false" %>'/>
</ItemTemplate>
Hope this helps.
Off the top of my head, I think what you will have to do is something along the lines of the following...
<asp:TemplateField HeaderText="Checkbox">
<ItemTemplate>
<asp:CheckBox ID="MasterCheckbox" runat="server" AutoPostBack="true" OnCheckedChanged="checkGridViewChkBox" />
</ItemTemplate>
</asp:TemplateField>
With the following code behind.
CheckBox MasterCheckbox;
CheckBox ChildCheckbox;
private void checkGridViewChkBox()
{
int i;
int x = GridView1.Rows.Count;
for (i = 0; i < x; i++) //loop through rows
{
findControls(i);
if (MasterCheckbox.Checked)
{
ChildCheckbox.Enabled = true;
}else{
ChildCheckbox.Enabled = false;
}
}
}
private void findControls(int i)
{
MasterCheckbox = (CheckBox)(GridView1.Rows[i].FindControl("MasterCheckbox"));
ChildCheckbox = (CheckBox)(GridView1.Rows[i].FindControl("ChildCheckbox"));
}
It's not terribly efficient but works ok.
Similar to my other question:
I have a ListView bound to a Dictionary. Then I have a nested ListView for the dictionary's value's integers.
I need to limit the number of items bound to the nested list to something like 5, and show a more button in the template.
I can't find a way to get the more button to work, and to correctly limit the number at the same time. I have it working as one or the other right now.
Any ideas? Thanks!
UPDATE:
The markup looks something like this:
<asp:ListView runat="server" ID="MainListView" ItemPlaceholderID="PlaceHolder2">
<LayoutTemplate>
<asp:PlaceHolder runat="server" ID="PlaceHolder2" />
</LayoutTemplate>
<ItemTemplate>
<h1>My Main ListView - <%# Eval("Key") %></h1>
<asp:ListView runat="server" ID="NestedListView" ItemPlaceholderID="PlaceHolder3"
DataSource='<%# Eval("Value") %>' >
<LayoutTemplate>
<h2>One of many Nested ListViews</h2>
<asp:PlaceHolder runat="server" ID="PlaceHolder3" />
</LayoutTemplate>
<ItemTemplate>
<asp:LinkButton runat="server" ID="AnInteger" Text='<%# Eval("value") %>'></asp:LinkButton>
<br />
</ItemTemplate>
</asp:ListView>
<asp:LinkButton runat="server" ID="uxMoreIntegers" Text="More..." Visible="false" OnClick="uxMoreIntegers_Click"></asp:LinkButton>
</ItemTemplate>
</asp:ListView>
DataBind the main ListView anyway you want.
DataBind the nested ListView programmatically in the ItemDataBound event for the main ListView
Code:
protected void uxListView_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
ListViewDataItem item = (ListViewDataItem)e.Item;
// Get the bound object (KeyValuePair from the dictionary)
KeyValuePair<string, List<int>> nestedIntegerList = (KeyValuePair<string, List<int>>)item.DataItem;
// Get our nested ListView for this Item
ListView nestedListView = (ListView)e.Item.FindControl("uxNestedListView");
// Check the number of items
if (nestedIntegerList.Value.Count > 5)
{
// There are more items than we want to show, so show the "More..." button
LinkButton button = (LinkButton)item.FindControl("uxMore");
button.Visible = true;
}
// Bind the nestedListView to wahtever you want
nestedListView.DataSource = nestedIntegerList.Value.Take(5);
nestedListView.DataBind();
}
}
The Take method will return the first 5 items in your list, but won't modify the list itself. You can then simply check the number of items in the list to determine if the more button needs to be enabled.
someList.Take(5); //use these items in your ListView
moreButton.Enabled = (someList.Count > 5);