Displaying image on a separate page - asp.net

I have a image datatype which on click of a linkbutton needs to be displayed on a seperate page
aspx page
detail view:
<asp:TemplateField HeaderText="Evidence (if any)">
<ItemTemplate>
<asp:LinkButton ID="lbEvidence" runat="server"
Text='<%# DataBinder.Eval(Container.DataItem, "Evidence").ToString() == String.Empty ? "None" : DataBinder.Eval(Container.DataItem, "Evidence")%>'
CommandName="Select" CommandArgument = '<%# DataBinder.Eval(Container.DataItem, "Complaint_Id") %>'> </asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
ImageHandler.ashx
<%# WebHandler Language="C#" Class="FMMadminModule.imageHandler" %>
using System;
using System.Web;
using System.Data;
using System.Web.SessionState;
namespace FMMadminModule
{
public class imageHandler : IHttpHandler, IReadOnlySessionState
{
DataTable dt;
int key;
byte[] imageOut;
public void ProcessRequest(HttpContext context)
{
HttpResponse response = context.Response;
HttpRequest request = context.Request;
context.Response.ContentType = "image/jpeg";
response.BufferOutput = false;
// get the key, the index into the DataTable
key = Convert.ToInt32(request.QueryString["Complaint_ID"]);
// Prepare the datatable to hold the SNo key and the jpeg image, which will be written out
dt = new DataTable();
dt = (DataTable)context.Session["dt"];
if (!dt.Rows[key]["Evidence"].Equals(null))
{
imageOut = (byte[])dt.Rows[key]["Evidence"];
response.OutputStream.Write(imageOut, 0, imageOut.Length);
}
}
public bool IsReusable
{
get
{
return false;
}
}
}
}
How would I display the image on a separate page?
This is how aspx.cs looks like
protected void dvResolveComplaint_ItemCommand(object sender, DetailsViewCommandEventArgs e)
{
if (e.CommandName == "Select")
{
DetailsViewRow row = dvResolveComplaint.Rows[5];
//String RowId = (e.NewSelectedIndex).ToString();
Type csType = this.GetType();
String strScript = "<script> ";
strScript += #"var newWindow = window.open('imageHandler.ashx?Complaint_ID=" + e.CommandArgument + #"', 'Evidence', ' height=450, center:yes, width=600, status=no, resizable= yes, menubar=no, toolbar=no, location=yes, scrollbars=no, status=no')";
strScript += "</script>";
ClientScript.RegisterClientScriptBlock(csType, "ViewEvidence", strScript);
dvResolveComplaint.Attributes.Add("OnClick", strScript);
}
}

this is way overcomplicated. You don't need the linkbutton at all, just write an anchor-wrapped image in your item template and call it a day, e.g.:
<img src='url_to_your_handler' alt='complaint image' />

Related

how to check the duplicate filename in asp:fileupload?

i have an updatepanel and inside of it the contenttemplate is an asp:FileUpload..now when i will try to choose the file i want to check the filename in the database..i know my database part but how will i call the function in the server like for asp:TextBox i can use OnTextChanged something like that..but for asp:FileUpload is there anything by which i can check the filename and without clicking the button add?? my code
<asp:UpdatePanel runat="server" ID="fileupdatepanel">
<ContentTemplate>
<asp:FileUpload ID="tutorialupload" runat="server" AutoPostBack="true" OnLoad="filename_Changed" />
<asp:Label runat="server" ID="f1"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="addbttu" runat="server" Text="Add" OnClick="addtutorial_Click" />
my aspx.cs code
protected void filename_Changed(object sender, EventArgs e)
{
string con = " ";
con = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
SqlConnection objsqlconn = new SqlConnection(con);
objsqlconn.Open();
string tuname = tutorialupload.PostedFile.FileName;
tuname = tuname.Substring(0, tuname.LastIndexOf("."));
SqlCommand objcmd = new SqlCommand("Select tutorialid from tutorialtable where tutorialname='" + tuname + "'", objsqlconn);
SqlDataReader grpIDreader = objcmd.ExecuteReader();
grpIDreader.Read();
if (grpIDreader.HasRows)
{
f1.Text = "Duplicate filename.Sorry.";
}
else
{
f1.Text = "";
}
objsqlconn.Close();
}
now when i will choose the file..i want to call this function filename_Changed() and it will give me the result whether the filename is present or not..so i want to do it without clicking my the add button??
You should use the has file property, when true do you DB check, something like this
protected void UploadButton_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
// Before attempting to save the file, do something
else
// Notify the user that a file was not uploaded.
UploadStatusLabel.Text = "You did not specify a file to upload.";
}
Here is how you can detect the change in the selected file name using JavaScript through the FileUpload onChange event.
ASPX Page: Make sure to set EnablePageMethods = true in the ScriptManager object.
<asp:ScriptManager ID="ScriptManager1" runat="server" EnablePageMethods="true"></asp:ScriptManager>
<asp:UpdatePanel runat="server" ID="fileupdatepanel">
<ContentTemplate>
<asp:FileUpload ID="tutorialupload" runat="server" OnChange="CheckFileName(this)" />
<asp:Label runat="server" ID="f1"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
<asp:Button ID="addbttu" runat="server" Text="Add" OnClick="addtutorial_Click" />
JavaScript:
function CheckFileName(oFile)
{
PageMethods.FileNameChecker(oFile.value, OnSucceeded);
}
function OnSucceeded(result, userContext, methodName)
{
lbl = document.getElementById('<%=f1.ClientID %>');
if (methodName == "FileNameChecker")
{
if (result == true)
{
lbl.innerHTML = 'Duplicate filename.Sorry.';
lbl.style.color = "red";
}
else
{
lbl.innerHTML = '';
}
}
}
C# Code-Behind: You can call a WebMethod to check if the new selected filename exists in the DB:
You need to reference the following:
using System.Web.Services;
Then add the following method and make sure you put [WebMethod] before method declaration:
[WebMethod]
public static bool FileNameChecker(string newFileName)
{
string con = " ";
con = ConfigurationManager.ConnectionStrings["ConnectionString"].ToString();
SqlConnection objsqlconn = new SqlConnection(con);
objsqlconn.Open();
string x = newFileName.Substring(0,newFileName.LastIndexOf("\\"));
string tuname = newFileName.Substring(newFileName.LastIndexOf("\\") + 1, newFileName.Length - x.Length - 1);
tuname = tuname.Substring(0, tuname.LastIndexOf("."));
SqlCommand objcmd = new SqlCommand("Select tutorialid from tutorialtable where tutorialname='" + tuname + "'", objsqlconn);
SqlDataReader grpIDreader = objcmd.ExecuteReader();
grpIDreader.Read();
bool found = false;
if (grpIDreader.HasRows)
found = true;
objsqlconn.Close();
return found;
}

iTextSharp - corrupt PDF and document close error

This is very close to working. Not sure why I am getting an error at document.Close() or why I am getting a corrupt pdf when I delete document.Close().
It seems to not be posting any info to the pdf.
The code:
Main page with the button the user clicks:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="EventList.ascx.cs"
Inherits="Objects_EventList" %>
<asp:ListView runat="server" ID="lstvwEvents"
OnItemDataBound="lstvwEvents_OnItemDataBound">
<LayoutTemplate>
<asp:ImageButton BorderStyle="0" CssClass="submitbutton" runat="server" AlternateText="Get PDF" ID="LinkButton1" OnClick="btnGenerateReport" />
<div class="eventtease" style="width: 249px;border-bottom: 1px solid #c0c06b;padding-right: 10px;padding-top: 10px;height: 300px;overflow: auto;">
<asp:Literal runat="server" ID="itemPlaceholder" />
<div style="clear: both;"></div>
</div>
</LayoutTemplate>
<ItemTemplate>
<h3 style="clear: both;border-top: 1px solid #c0c06b;padding-top: 10px;"><asp:Literal runat="server" ID="ltrlShortDate" /><br /><%# Eval("EventName").ToString().ToUpper() %><br />(<asp:Literal runat="server" ID="ltrlTimes" />)</h3>
<p class="eventdescription" style="font: normal normal normal 7.5pt/normal Arial, Sans-Serif;margin-top: 3px;">
<%# Eval("Description") %>
</p>
<asp:HyperLink runat="server" ID="lnkLearnMore" Text="LEARN MORE" CssClass="learnmore" Visible="false" />
</ItemTemplate>
Here is the code behind:
using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using iTextSharp.text;
using iTextSharp.text.pdf;
using iTextSharp.text.html.simpleparser;
using System.IO;
public partial class Objects_EventList : System.Web.UI.UserControl
{
public string city;
public int showcount;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
Load_Events();
};
}
protected void Load_Events()
{
EventsDataContext edc = new EventsDataContext();
var events = (from e in edc.tblEvents_Cafes
where e.EventDateTime >= DateTime.Now && e.VenueCity.Trim() == city.Trim() && (e.VenueName.Contains("Café") || e.VenueName.Contains("Cafe") )
orderby e.EventDateTime
select new
{
EventName = e.EventName,
EventDate = e.EventDate,
EventTime = e.EventTime,
Description = edc.tblEvents_Cafe_Descriptions.OrderBy(d => d.Priority).Where(d => d.Keywords.ToLower() == e.EventName.ToLower()).Select(d => d.Description).First(), // edc.tblEvents_Cafe_Descriptions.OrderBy(d => d.Priority).Where(d => d.Keywords.ToLower() == e.EventName.ToLower() || d.Keywords.ToLower().CompareTo(e.EventName.ToLower()) >= 0).Select(d => d.Description).First()
}).Take(showcount);
lstvwEvents.DataSource = events;
lstvwEvents.DataBind();
}
protected void lstvwEvents_OnItemDataBound(Object sender, ListViewItemEventArgs e)
{
ListViewDataItem dataItem = (ListViewDataItem)e.Item;
if (e.Item.ItemType == ListViewItemType.DataItem)
{
var tempevent = dataItem.DataItem;
Type t = tempevent.GetType();
DateTime tempdate;
if (DateTime.TryParse((t.GetProperty("EventDate").GetValue(tempevent, null)).ToString(), out tempdate))
{
Literal ltrlShortDate = new Literal();
ltrlShortDate = (Literal)e.Item.FindControl("ltrlShortDate");
ltrlShortDate.Text = tempdate.ToString("MM/dd/yyyy");
}
if (DateTime.TryParse((t.GetProperty("EventTime").GetValue(tempevent, null)).ToString(), out tempdate))
{
Literal ltrlTimes = new Literal();
ltrlTimes = (Literal)e.Item.FindControl("ltrlTimes");
ltrlTimes.Text = tempdate.ToString("hh:mm tt");
}
}
}
private void GeneratePDF(string path, string fileName, bool download, string text)
{
var document = new Document();
try {
if (download) {
PdfWriter.GetInstance(document, Response.OutputStream);
} else {
PdfWriter.GetInstance(document, new FileStream(path + fileName, FileMode.Create));
}
StringBuilder strB = new StringBuilder();
document.Open();
if (text.Length.Equals(0)) {
lstvwEvents.DataBind();
using (StringWriter sWriter = new StringWriter(strB)) {
using (HtmlTextWriter htWriter = new HtmlTextWriter(sWriter)) {
ListView lv1 = lstvwEvents;
lv1.RenderControl(htWriter);
}
}
} else {
strB.Append(text);
}
using (TextReader sReader = new StringReader(strB.ToString())) {
List<IElement> list = HTMLWorker.ParseToList(sReader, new StyleSheet());
foreach (IElement elm in list) {
document.Add(elm);
}
}
} catch (Exception ee) {
ee.ToString();
} finally {
document.Close();
}
}
protected void btnGenerateReport(object sender, EventArgs e)
{
string fileName = "Calendar.pdf";
GeneratePDF("", fileName, true, "");
Response.Clear();
Response.ContentType = "application/pdf";
Response.AddHeader("content-disposition", "attachment; filename=" + fileName);
Response.Flush();
Response.End();
}
}

How to generate a print preview in a single button click in report viewer?

This is my aspx page..................
<asp:Panel ID="UpdatePanel1" runat="server" Visible="false" >
<rsweb:ReportViewer ID="ReportingForPrintingReportViewer" runat="server"
Width="100%" Height="100%" Font-Names="Verdana" Font-Size="8pt"
InteractiveDeviceInfos="(Collection)" WaitMessageFont-Names="Verdana"
WaitMessageFont-Size="14pt">
<LocalReport ReportPath="Report.rdlc">
<DataSources>
<rsweb:ReportDataSource DataSourceId="ObjectDataSource2" Name="DataSet1" />
</DataSources>
</LocalReport>
</rsweb:ReportViewer>
<asp:ObjectDataSource ID="ObjectDataSource2" runat="server"
SelectMethod="GetData" TypeName="DataSet1TableAdapters.tblTotalFeeTableAdapter">
</asp:ObjectDataSource>
</asp:Panel>
<asp:Button ID="btnSubmit" runat="server" Text="Submit" Width="150px"
onclick="btnSubmit_Click" />
<asp:Button ID="btnReset" runat="server" Text="Reset" Width="150px" />
<asp:Button ID="btnCreateBill" runat="server" Text="CreateBill" Width="150px"
onclick="btnCreateBill_Click"/>
<asp:PopupControlExtender ID="btnCreateBill_PopupControlExtender" OffsetX="-1100" OffsetY="115"
runat="server" DynamicServicePath="" Enabled="True" ExtenderControlID=""
TargetControlID="btnCreateBill" PopupControlID="UpdatePanel1">
</asp:PopupControlExtender>
This is my cs page
protected void btnCreateBill_Click(object sender, EventArgs e)
{
DisplayReport();
UpdatePanel1.Visible = true;
}
private DataTable TotalInfoData()
{
try
{
//DataClassesDataContext db = null;
//db = new DataClassesDataContext();
//var s = from p in db.tblTotalFeess
// where p.Class == ClassDropDownList.SelectedItem.Value && p.StudentID == Convert.ToInt32(StudentNameDropDownList.SelectedValue)
// select p;
//DataTable dt = new DataTable();
//SQLHelper sqhlpr = new SQLHelper();
//sqhlpr.SqlText = "select * from tblTotalFee where Class='" + ClassDropDownList.SelectedItem.Value + "'" + "and StudentID='" + StudentNameDropDownList.SelectedValue + "'";
//DataTable dt = sqhlpr.getDataTable(false);
//return dt;
try
{
// Open Sql Connection
SqlConnection SqlCon = new SqlConnection(#"Data Source=PRATIKPC;Initial Catalog=dbbilling2.0;Integrated Security=True");
SqlCon.Open();
// Create a Command
SqlCommand SqlComm = new SqlCommand();
SqlComm.Connection = SqlCon;
SqlComm.CommandType = CommandType.Text;
SqlComm.CommandText = "select * from tblTotalFee where Class='" + ClassDropDownList.SelectedItem.Value + "'" + "and StudentID='" + StudentNameDropDownList.SelectedValue + "'";
// Create instance of Northwind DataSetXSD
DataSet1.tblTotalFeeDataTable dtbl = new DataSet1.tblTotalFeeDataTable();
// Set a Data Commands
SqlDataAdapter SqlDa = new SqlDataAdapter(SqlComm);
SqlDa.Fill(dtbl); // Fill Data in NorthwindDataSet Object.
return dtbl;
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
private void DisplayReport()
{
try
{
// Clear the Data Source
ReportingForPrintingReportViewer.LocalReport.DataSources.Clear();
// Set a DataSource to the report
// First Parameter - Report DataSet Name
// Second Parameter - DataSource Object i.e DataTable
ReportingForPrintingReportViewer.LocalReport.DataSources.Add(new ReportDataSource("DataSet1", TotalInfoData()));
// OR Set Report Path
ReportingForPrintingReportViewer.LocalReport.ReportPath = HttpContext.Current.Server.MapPath("~/Report.rdlc");
// Refresh and Display Report
ReportingForPrintingReportViewer.LocalReport.Refresh();
}
catch (Exception ex)
{
throw new Exception(ex.Message);
}
}
I have to click btnCreateBill twice to generate report viewer. Why? And how can I generate report viewer in a single click of a button?
Are you call your Get Data method(Your Data Source load method
) in Inside of !ispostback ?
for look this
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
GetData()// Your Data Source load method
}
}
This is Aspx file........................
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"
CodeBehind="AccountReportParameter.aspx.cs" Inherits="TexERP.ReportSSRS.AccountReportParameter" %>
<%# Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>
<asp:Content ID="Content1" ContentPlaceHolderID="HeadContent" runat="server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> <asp:UpdatePanel ID="updpnlLiteral" runat="server">
<ContentTemplate>
<asp:Panel ID="pnlAddRecord" runat="server" BackColor="White" Height="150px" Width="600px"
Visible="true">
<td align="right" colspan="4">
<asp:Button ID="btnSubmit" runat="server" Text="Show Report" OnClick="btnSubmit_Click"
ValidationGroup="FinalSave" />
<asp:Button ID="btnCancel" runat="server" Text="Reset" UseSubmitBehavior="false"
OnClick="btnCancel_Click" />
</asp:Panel>
<rsweb:ReportViewer ID="rptvwMain" runat="server" Width="907px" Height="850px" Font-Names="Verdana"
Font-Size="8pt" ProcessingMode="Remote" ShowCredentialPrompts="false" InteractiveDeviceInfos="(Collection)"
ShowZoomControl="true">
</rsweb:ReportViewer>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
This is cs file...........
using System;
using System.Collections.Generic;
using System.Data;
using System.Net;
using BusinessAccessLevel;
using BusinessAccessLevel.Masters;
using Microsoft.Reporting.WebForms;
namespace TexERP.ReportCrystal
{
public partial class AccountReportParameter : System.Web.UI.Page
{
AccountReportBAL objAccountReportBAL;
clsSession objSession;
string pstrType;
protected void Page_Load(object sender, EventArgs e)
{
objAccountReportBAL = new AccountReportBAL();
objSession = new clsSession();
pstrType = Request.QueryString["Type"];
if (Session["objSession"] != null)
{
objSession = Session["objSession"] as clsSession;
}
objAccountReportBAL = new AccountReportBAL();
if (!IsPostBack)
{
RadDtpFromDate.SelectedDate = Convert.ToDateTime(objSession.FyFromDate);
RadDtpToDate.SelectedDate = Convert.ToDateTime(objSession.FyToDate);
}
rptvwMain.LocalReport.Refresh();
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
string pstrType;
pstrType = Request.QueryString["Type"];
LoadReport();
}
public class CustomReportCredentials : Microsoft.Reporting.WebForms.IReportServerCredentials
{
// local variable for network credential.
private string _UserName;
private string _PassWord;
private string _DomainName;
public CustomReportCredentials(string UserName, string PassWord, string DomainName)
{
_UserName = UserName;
_PassWord = PassWord;
_DomainName = DomainName;
}
public System.Security.Principal.WindowsIdentity ImpersonationUser
{
get
{
return null; // not use ImpersonationUser
}
}
public System.Net.ICredentials NetworkCredentials
{
get
{
// use NetworkCredentials
return new NetworkCredential(_UserName, _PassWord, _DomainName);
}
}
public bool GetFormsCredentials(out Cookie authCookie, out string user, out string password, out string authority)
{
// not use FormsCredentials unless you have implements a custom autentication.
authCookie = null;
user = password = authority = null;
return false;
}
}
void LoadReport()
{
string strCompanyName = objSession.SelCompanyName;
string strHeading = "";
string strBranchName = objSession.SelBranchName;
rptvwMain.ProcessingMode = ProcessingMode.Remote;
rptvwMain.ServerReport.ReportServerCredentials = new CustomReportCredentials(AppConfig.ReportServerUserName, AppConfig.ReportServerPassword, AppConfig.ReportServerDomain);
string strReportServerUrl = AppConfig.ReportServerUrl + AppConfig.ReportServerFolder;
rptvwMain.ServerReport.ReportServerUrl = new Uri(strReportServerUrl);
List<ReportParameter> parameters = new List<ReportParameter>();
if(pstrType == "GL")
{
strHeading = "General Ledger";
rptvwMain.ServerReport.ReportPath = "/Account/AccountGeneralLedger";
}
parameters.Add(new ReportParameter("FyId", Convert.ToInt16(objSession.FyId).ToString()));
parameters.Add(new ReportParameter("AccountGroupId", cmbAccountGroup.SelectedValue));
parameters.Add(new ReportParameter("LedgerId", cmbLedgerId.SelectedValue));
parameters.Add(new ReportParameter("BranchId", Convert.ToInt64(objSession.BranchId).ToString()));
parameters.Add(new ReportParameter("StDate", Convert.ToDateTime(RadDtpFromDate.SelectedDate).ToString()));
parameters.Add(new ReportParameter("EnDate", Convert.ToDateTime(RadDtpToDate.SelectedDate).ToString()));
parameters.Add(new ReportParameter("CompanyName", strCompanyName.ToString()));
parameters.Add(new ReportParameter("BranchName", strBranchName.ToString()));
parameters.Add(new ReportParameter("Heading",strHeading.ToString()));
rptvwMain.ServerReport.SetParameters(parameters);
rptvwMain.ServerReport.SetDataSourceCredentials(new[] { new DataSourceCredentials() { Name =AppConfig.ReportServerDataSource , UserId = AppConfig.ReportServerDSUserName, Password = AppConfig.ReportServerDSPassword } });
rptvwMain.ShowZoomControl = true;
rptvwMain.ServerReport.Refresh();
}
}
}
Try this code as reference code................

OnCheckedChanged Nested Listview Controls

I have the following nested listview...
<asp:ListView ID="lvwRiskQuestions" runat="server" ItemPlaceholderID="QuestionItemPlaceholder">
<LayoutTemplate>
<asp:PlaceHolder ID="QuestionItemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<%# Eval("DESCRIPTION")%>
<asp:ListView ID="lvwAnswers" runat="server" ItemPlaceholderID="AnswerItemPlaceholder" DataSource='<%# Eval("Answers")%>'>
<LayoutTemplate>
<asp:PlaceHolder ID="AnswerItemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<asp:RadioButton ID="rdbSelect" runat="server" AutoPostBack="true" OnCheckedChanged="rdbSelectChanged"/>
<%# Eval("Description")%>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:ListView>
I get hold of the radio buttons OnCheckedChanged like so...
Protected Sub rdbSelectChanged(ByVal sender As Object, ByVal e As System.EventArgs)
Dim rb1 As RadioButton = CType(sender, RadioButton)
Dim lvwAnswers = DirectCast(lvwRiskQuestions.FindControl("lvwAnswers"), ListView)
For Each row As ListViewItem In lvwAnswers.Items
Dim rb As RadioButton = row.FindControl("rdbSelect")
If rb IsNot Nothing AndAlso rb.Checked Then
rb.Checked = False
End If
Next
rb1.Checked = True
End Sub
The problem i have is 'lvwAnswers' is Nothing. I'm guessing im not doing my findcontrol correctly.
Any help greatly appreciated.
If you're just generating a list of radio-buttons for the answers, you could use the RadioButtonList control. This would generate the correct HTML so that only one answer could be selected per question without having to post-back to de-select the other options.
If your answer template contains more than a single RadioButton, things get more complicated. When it's not hosted in a RadioButtonList, the RadioButton uses the UniqueID of the parent NamingContainer to build its unique group name. Unfortunately, in your example, the NamingContainer will be the ListViewDataItem from the lvwAnswers list, and each answer will have a different ID.
What you need is a RadioButton which will look at the NamingContainer's NamingContainer to generate its group name. You could either re-implement the RadioButton control, or use a little bit of reflection to update the private _uniqueGroupName field:
[ToolboxData("<{0}:ListRadioButton runat=\"server\" />")]
public class ListRadioButton : RadioButton
{
private static readonly FieldInfo UniqueGroupNameField = FindUniqueGroupNameField();
private string _uniqueGroupName;
private static FieldInfo FindUniqueGroupNameField()
{
return typeof(RadioButton).GetField("_uniqueGroupName",
BindingFlags.NonPublic | BindingFlags.Instance);
}
protected virtual string CreateUniqueGroupName()
{
string result = GroupName;
if (string.IsNullOrEmpty(result))
{
result = ID;
}
if (string.IsNullOrEmpty(result))
{
result = UniqueID;
}
else
{
Control container = NamingContainer;
if (container != null)
{
if (container is IDataItemContainer)
{
container = container.NamingContainer ?? container;
}
result = container.UniqueID + base.IdSeparator + result;
}
else
{
string uniqueID = UniqueID;
if (!string.IsNullOrEmpty(uniqueID))
{
int index = uniqueID.LastIndexOf(base.IdSeparator);
if (index != -1)
{
result = uniqueID.Substring(0, 1 + index) + result;
}
}
}
}
return result;
}
private void EnsureUniqueGroupName()
{
if (_uniqueGroupName == null)
{
string value = CreateUniqueGroupName();
if (UniqueGroupNameField != null) UniqueGroupNameField.SetValue(this, value);
_uniqueGroupName = value;
value = base.Attributes["value"];
if (string.IsNullOrEmpty(value))
{
base.Attributes["value"] = UniqueID;
}
}
}
protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
EnsureUniqueGroupName();
return base.LoadPostData(postDataKey, postCollection);
}
protected override void Render(HtmlTextWriter writer)
{
EnsureUniqueGroupName();
base.Render(writer);
}
}
With that control in place and registered using the site prefix, you can change your code to:
<asp:ListView ID="lvwRiskQuestions" runat="server" ItemPlaceholderID="QuestionItemPlaceholder">
<LayoutTemplate>
<asp:PlaceHolder ID="QuestionItemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<%# Eval("DESCRIPTION") %>
<asp:ListView ID="lvwAnswers" runat="server" ItemPlaceholderID="AnswerItemPlaceholder" DataSource='<%# Eval("Answers")%>'>
<LayoutTemplate>
<asp:PlaceHolder ID="AnswerItemPlaceholder" runat="server" />
</LayoutTemplate>
<ItemTemplate>
<site:ListRadioButton ID="rdbSelect" runat="server"
Text='<%# Eval("Description") %>'
/>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:ListView>
In the rendered HTML, the radio-buttons for each question will then have the same name, and you will only be able to select a single answer per question, without having to post the entire page on each selection.
I'd like to point out that this "copy/paste" code doesn't work and was taken from a comment on codeproject (Comment titled Another Option). The original code does work.
Here it is :
using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Reflection;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
[AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
[AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal)]
public class SimpleRadioButton : RadioButton
{
private static readonly FieldInfo UniqueGroupNameField = FindUniqueGroupNameField();
private string _uniqueGroupName;
private static FieldInfo FindUniqueGroupNameField()
{
return typeof(RadioButton).GetField("_uniqueGroupName",
BindingFlags.NonPublic | BindingFlags.Instance);
}
protected virtual string CreateUniqueGroupName()
{
string result = this.GroupName;
if (string.IsNullOrEmpty(result))
{
result = this.ID;
}
if (string.IsNullOrEmpty(result))
{
result = this.UniqueID;
}
else
{
Control container = this.NamingContainer;
if (null != container)
{
if (container is IDataItemContainer)
{
container = container.NamingContainer ?? container;
}
result = container.UniqueID + base.IdSeparator + result;
}
else
{
string uniqueID = this.UniqueID;
if (!string.IsNullOrEmpty(uniqueID))
{
int index = uniqueID.LastIndexOf(base.IdSeparator);
if (-1 != index)
{
result = uniqueID.Substring(0, 1 + index) + result;
}
}
}
}
return result;
}
private void EnsureUniqueGroupName()
{
if (null == _uniqueGroupName)
{
string value = this.CreateUniqueGroupName();
if (null != UniqueGroupNameField) UniqueGroupNameField.SetValue(this, value);
_uniqueGroupName = value;
// Make sure we have a value attribute:
value = base.Attributes["value"];
if (string.IsNullOrEmpty(value))
{
base.Attributes["value"] = this.UniqueID;
}
}
}
protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
{
this.EnsureUniqueGroupName();
return base.LoadPostData(postDataKey, postCollection);
}
protected override void Render(HtmlTextWriter writer)
{
this.EnsureUniqueGroupName();
base.Render(writer);
}
}

ASP.net Repeater not binding values

I have a repeater defined as
<asp:Repeater id="rep1" runat="server">
<ItemTemplate>
<%#Eval("name")%>
</ItemTemplate>
</asp:Repeater>
The code behind is as
try
{
SqlConnection xconn = new SqlConnection();
xconn.ConnectionString = #"Data Source=XXXXXX;Trusted_Connection=yes;database=master";
xconn.Open();
lbl1.Text = "Connected to SQL";
SqlCommand ycmd = new SqlCommand("select * from student",xconn);
SqlDataReader dr = ycmd.ExecuteReader();
cdcatalog.DataSource = dr;
cdcatalog.DataBind();
}
catch (Exception)
{
lbl1.Text= "Cannot connect to SQL";
}
Why does it not bind the data in the repeater?
Why are you binding data readers to a repeater? I would recommend you using strongly typed objects. So start by defining a model that will represent your data:
public class Student
{
public string Name { get; set; }
}
then a method to fetch those students:
public IEnumerable<Student> GetStudents()
{
using (var conn = new SqlConnection("Data Source=XXXXXX;Trusted_Connection=yes;database=master"))
using (var cmd = conn.CreateCommand())
{
conn.Open();
cmd.CommandText = "SELECT Name FROM Students;";
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
yield return new Student
{
Name = reader.GetString(reader.GetOrdinal("Name"));
}
}
}
}
}
and then bind the repeater:
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
rep1.DataSource = GetStudents().ToArray();
rep1.DataBind();
}
}
and in the view:
<asp:Repeater id="rep1" runat="server">
<ItemTemplate>
<%# Eval("Name") %>
</ItemTemplate>
</asp:Repeater>
Also note that the name of the repeater is rep1 so that's what you should use in your code behind.
the ID of your repeater is rep1 whereas you are databinding cdcatalog. I guess your problem is there. What is this cdcatalog?

Resources