How to use databind records in inline if statements - asp.net

here is my problem:
I've got a repeater on my asp.net (VB):
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Question_Number") %>' />
<%#Eval("Question_Desc")%>
Now what I want to do is, check a value that I haven't used called "Question_Type" which could be = 1, 2 or 3 depending if it is multiple choice, short answer, etc.
I have tried this:
<%
if Eval("Question_type") = 1 then
Response.Write(" <asp:RadioButton runat=""server"">test1</asp:RadioButton>")
Response.Write(" <asp:RadioButton runat=""server"">test2</asp:RadioButton>")
Response.Write(" <asp:RadioButton runat=""server"">test3</asp:RadioButton>")
end if
%>
and I get this error:
Databinding methods such as Eval(), XPath(), and Bind() can only be used in the context of a databound control.
HOW can I use this value in a if statement???

You are going to need to handle the ItemDataBound event and manually handle the values there.
Here is how I might approach the problem given this repeater:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="HandleQuestionType">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("Question_Number") %>' />
<%#Eval("Question_Desc")%>
<asp:PlaceHolder ID="phQuestions" runat="server" />
</ItemTemplate>
</asp:Repeater>
Here is my event handler for getting the possible answers to a radio button list:
protected void HandleQuestionType(object sender, RepeaterItemEventArgs e)
{
// Execute the following logic for Items and Alternating Items.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var question = e.Item.DataItem as Question;
var placeHolder = e.Item.FindControl("phQuestions") as PlaceHolder;
if(question != null && placeHolder != null)
{
if(question.Question_Type == QuestionTypeEnum.MultipleChoice)
{
var radioList = new RadioButtonList
{
DataTextField = "Answer",
DataValueField = "ID",
DataSource = GetPossibleAnswers()
};
radioList.DataBind();
placeHolder.Controls.Add(radioList);
}
}
}
}

Related

how to set control's id dynamically in asp.net

how can is set id dynamic with Eval method and setting the id from sql database to a controller , like this
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="articlesqlfetch">
<ItemTemplate>
<strong > <%# Eval("title") %> </strong>
<br>
<-! this is the line ->
<asp:HyperLink ID="_<%# Eval("id") %>" runat="server">قراءة المزيد</asp:HyperLink>
</ItemTemplate>
when do this it give me a Parser Error
Using Eval() to provide dynamically generated ID is not allowed because you cannot bind to ID property of server controls, hence this code is wrong:
<asp:HyperLink ID="_<%# Eval("id") %>" runat="server">some text</asp:HyperLink>
Instead, use ItemDatabound event for repeater control like this (assumed your ID is auto-generated identity field):
Markup (ASPX)
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="articlesqlfetch"
OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<%-- repeater contents --%>
<asp:HyperLink ID="Hyperlink1" runat="server">some text</asp:HyperLink>
</ItemTemplate>
</asp:Repeater>
Code-behind
protected void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
HyperLink hyperlink = e.Item.FindControl("Hyperlink1") as HyperLink;
if (hyperlink != null)
{
hyperlink.ID = "_" + (e.Item.ItemIndex + 1).ToString(); // set ID from bound data
hyperlink.ClientIDMode = ClientIDMode.Static;
hyperlink.NavigateUrl = "some/uri/here"; // optional
// other stuff
}
}

ASP.Net DropDownList selected value missing

At the beginning I have to say that I tried to find the answer... And yes I'm new in ASP.Net world :)
I would like to use DropDownList in an EditItemTemplate field in GridView. I found I cannot set parametr SelectedValue. It's missing. When I try to set it in code behind it seems to ddlEditPermissions doesn't exists.
<asp:TemplateField HeaderText="opravneni" SortExpression="opravneni">
<edititemtemplate>
<asp:DropDownList ID="ddlEditPermissions" runat="server" DataSource='<%# getPermissions() %>' OnPreRender="ddlEditPermissions_PreRender"/>
</edititemtemplate>
<insertitemtemplate>
<asp:TextBox ID="tbEditPermissions" runat="server" Text='<%# Bind("opravneni") %>'></asp:TextBox>
</insertitemtemplate>
<itemtemplate>
<asp:Label ID="lEditPermissions" runat="server" Text='<%# Bind("opravneni") %>'></asp:Label>
</itemtemplate>
I'm really confused. Could anyone advise me?
You can use RowDataBound of the GridView which gets triggered for every GridViewRow after it was constructed and databound:
protected void gridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow && e.Row.RowState == DataControlRowState.Edit)
{
var ddlEditPermissions = (DropDownList)e.Row.FindControl("ddlEditPermissions");
// bind DropDown manually
ddlEditPermissions.DataSource = getPermissions();
ddlEditPermissions.DataTextField = "Permission_Name"; // presumed text-column
ddlEditPermissions.DataValueField = "Permission_ID"; // presumed id-column
ddlEditPermissions.DataBind();
DataRowView dr = e.Row.DataItem as DataRowView; // you might need to change this type, use the debugger then to determine it
ddlEditPermissions.SelectedValue = dr["Permission_ID"].ToString(); // presumed foreign-key-column
}
}

How do I set dropdownlist selectedvalue in edit mode but not in gridview?

With the code below, when I click the Edit button, the selectvalue in gridview dropdownlist is retained while at the same time, retaining the rest of the dropdownlist values so user can select a different value.
Protected Sub RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow AndAlso gvCustomers.EditIndex = e.Row.RowIndex Then
Dim ddlRoles As DropDownList = DirectCast(e.Row.FindControl("ddlRoles"), DropDownList)
Dim query As String = "select RoleId, Roles from ROLES"
Dim cmd As New SqlCommand(query)
ddlRoles.DataSource = GetData(cmd)
ddlRoles.DataTextField = "Roles"
ddlRoles.DataValueField = "RoleId"
ddlRoles.DataBind()
ddlRoles.Items.FindByValue(TryCast(e.Row.FindControl("lblUserRole"), Label).Text).Selected = True
End If
End Sub
'//Markup:
<asp:Label ID="lblUserRole" runat="server" Text='<%# Eval("RoleId")%>' Visible = "false"></asp:Label>
<asp:DropDownList ID = "ddlRoles" runat = "server">
</asp:DropDownList>
These work fine for gridview.
However, I would like to change the codebehind to regular web form so I can manipulate the layout out better.
In other words, I have the layout like this:
First Name: _____________
Last Name: ______________
Roles: ________________
My understanding is that in gridview, layout is vertical and is not flexible.
We would like our layout to be horizontal.
Thank you in advance for your assistance
You have to use TemplateField and within that template you can specify your layout, which could contain multiple fields, and use different controls for Edit/Insert operations, like in the following sample:
Listing 1.
<asp:TemplateField HeaderText="Toll-Free: Area/Phone #">
<ItemTemplate>
(
<%# DataBinder.Eval( Container.DataItem, "A_TollFree_AreaCode" )%>
)
<%# DataBinder.Eval(Container.DataItem, "A_TollFree_Number")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtAreaCode" runat="server"
CssClass="phoneAreaCode" MaxLength="3"
Text='<%# Bind("A_TollFree_AreaCode") %>' />
<asp:TextBox ID="txtPhoneNumber" runat="server"
CssClass="phoneNumber" MaxLength="20"
Text='<%# Bind("A_TollFree_Number") %>' />
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="txtAreaCode" runat="server"
CssClass="phoneAreaCode" MaxLength="3"
Text='<%# Bind("A_TollFree_AreaCode") %>' />
<asp:TextBox ID="txtPhoneNumber" runat="server"
CssClass="phoneNumber" MaxLength="20"
Text='<%# Bind("A_TollFree_Number") %>' />
</EditItemTemplate>
</InsertItemTemplate>
</asp:TemplateField>
Regarding you second question (in comments), please refer to the Listing 2. that demonstrates the general technique of accessing various Controls in GridView:
Listing 2.
protected void GridView1_OnRowDataBound(object sender, GridViewRowEventArgs e)
{
try
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
string _strPhone = DataBinder.Eval(e.Row.DataItem, "txtPhoneNumber").ToString();
Button btn = (Button)e.Row.Cells[0].Controls[1];
}
}
catch { }
}
Best Regards,

Required field validater in repeater

I have a repeater control and textbox in that repeater. I want a required field validator in the textbox ho can i do this
<asp:Repeater id="myRep" OnItemDataBound="rep_ItemDataBound" runat="server">
<ItemTemplate>
<asp:TextBox id="tx" runat="server" />
<asp:RequiredFieldValidator id="myVal" ControlToValidate="tx" ErrorMessage="Required" runat="server" />
</ItemTemplate>
</asp:Repeater>
UPDATE
Add this to code-behind (also modify the markup a bit to subscribe to an event, see above):
protected void rep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RequiredFieldValidator val = (RequiredFieldValidator)e.Item.FindControl("myVal");
TextBox tb = (TextBox)e.Item.FindControl("tx");
val.ControlToValidate = tb.ID;
}
If you want all textboxes in a repeater to be validated by a single button click then thats simple like this
<asp:Repeater ID="rpt" runat="server">
<ItemTemplate>
<asp:TextBox ID="txt" runat="server">
</asp:TextBox>
<asp:RequiredFieldValidator ID="rqf" ControlToValidate="txt"
ErrorMessage="*" ValidationGroup = "TestValidationGroup" runat = "server">
</asp:RequiredFieldValidator>
</ItemTemplate>
</asp:Repeater>
<asp:Button ID = "btnSubmit" runat = "server" ValidationGroup = "TestValidationGroup" />
No need to check for any event for databound or anything.
You can set ControlToValidate value on repeater itemdatabound.
Try this one
<asp:Repeater ID="rptSample" runat="server">
<ItemTemplate>
Name:<br />
<asp:TextBox ID="txtName" runat="server"></asp:TextBox>
<asp:RequiredFieldValidator ID="rfvName" ControlToValidate="txtName" runat="server" Display="Static" ErrorMessage="Name field cannot be left blank"></asp:RequiredFieldValidator>
</ItemTemplate>
</asp:Repeater>
<br />
<asp:Button ID="btnSubmit" Text="Submit" runat="server" />
protected void myRep_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
((RequiredFieldValidator)e.Item.FindControl("myVal")).ValidationGroup = ((TextBox)e.Item.FindControl("tx")).UniqueID;
}
}
protected void Repeater_OnItemDataBound(object sender, RepeaterItemEventArgs e) {
tblData tbldata = e.Item.DataItem as tblData;
RequiredFieldValidator val = (RequiredFieldValidator)e.Item.FindControl("rfv");
if (tbldata.FieldName.ToUpper().Contains("NOT NULL")) {
TextBox tb = (TextBox)e.Item.FindControl("txtDATFieldName");
val.ControlToValidate = tb.ID;
}
else {
val.Enabled = false; // disable when you dont need a validator
}
}
Maybe you want have a validation per row... Set the validation group to a group per row like this
ValidationGroup='<%# "gropname" + Eval("Id") %>'
do this in the validator, textbox and the button
HTH
G.
I kept getting a duplicate key exception in RegisterExpandoAttribute trying to do this.
I was using a UserControl inside a repeater, when "OnDataBinding" instead of "ItemDataBinding"
This worked for me:
/// <summary>
/// Raises the <see cref="E:System.Web.UI.Control.DataBinding" /> event.
/// </summary>
/// <param name="e">An <see cref="T:System.EventArgs" /> object that contains the event data.</param>
protected override void OnDataBinding(EventArgs e)
{
base.OnDataBinding(e);
foreach (Control ct in this.Controls)
{
BaseValidator bv = ct as BaseValidator;
if (null == bv)
{
continue;
}
bv.ControlToValidate = this.FindControl(bv.ControlToValidate).ID;
bv.ValidationGroup = this.ValidationGroup;
}
}
And yes, I don't think it makes any sense either

display many rows from DB by normal line?

When I have a table in database with many rows
and I want to display them by normal line (Not with Gridview). Like:
You teach these classes:
class 1/1, class 2/1, class 3/1
we take (1/1 and 2/1 and 3/1) from database.
how can I do it ?
note: I use LINQ to deal with database.
Using a repeater seems to be the easiest way to me. It would look something like this.
<div>
You teach these classes:
<asp:Repeater
ID="rptListOfClasses"
runat="server"
DataSourceID="linqDataSource" >
<ItemTemplate>
<span> class <%# Eval("ClassDate") %>, </span>
</ItemTemplate>
</asp:Repeater>
</div>
<asp:ListView ID="lvClass" runat="server" DataSourceID="LinqDataSource1" OnItemDataBound ="lvResult_ItemDataBound" >
<LayoutTemplate>
You teach these classes:
<asp:PlaceHolder runat="server" ID="itemPlaceHolder" ></asp:PlaceHolder>
</LayoutTemplate>
<ItemTemplate>
<asp:Label ID="lblClass" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Class") + ", " %>' ></asp:Label>
</ItemTemplate>
</asp:ListView>
<asp:LinqDataSource ID="LinqDataSource1" runat="server"
ContextTypeName="MyDataContext" TableName="ClassList"
onselected="LinqDataSource1_Selected">
</asp:LinqDataSource>
Code Behind:
//remove the last comma(,)
public class Test : System.Web.UI.Page
{
int iCount = 0;
protected void lvResult_ItemDataBound(object sender, ListViewItemEventArgs e)
{
if (e.Item.ItemType == ListViewItemType.DataItem)
{
Label lblClass = e.Item.FindControl("lblClass") as Label;
ListViewDataItem lvItem = e.Item as ListViewDataItem ;
if (lblClass != null)
if (lvItem.DataItemIndex == (iCount - 1))
lblClass.Text = lblClass.Text.Substring(0, lblClass.Text.ToString().Length - 2);
}
}
protected void LinqDataSource1_Selected(object sender, LinqDataSourceStatusEventArgs e)
{
iCount = e.TotalRowCount;
}
}

Resources