GridView isn't reflecting AJAX changes - asp.net

I'm using AJAX right now to update my GridView when I search for a string of text in the gridview, or when I select from a dropdownlist what I want to order the Gridview by. This was working previously, but I had really messy code. So I've cleaned it up a little bit, added some parameters and such. Unfortunately, now, when the selectedindex of the dropdownlist is changed or when someone tries to search for a field, nothing happens - the page just refreshes. I'm also getting an exception saying "The SELECT item identified by the ORDER BY number 1 contains a variable as part of the expression identifying a column position. Variables are only allowed when ordering by an expression referencing a column name".
If you need to see any more code then please let me know!
public vieworders()
{
this.PreInit += new EventHandler(vieworders_PreInit);
}
void vieworders_PreInit(object sender, EventArgs e)
{
orderByString = orderByList.SelectedItem.Value;
fieldString = searchTextBox.Text;
updateDatabase(fieldString, orderByString);
}
protected void updateDatabase(string _searchString, string _orderByString)
{
string updateCommand = "SELECT fName,lName,zip,email,cwaSource,price,length FROM SecureOrders WHERE fName LIKE #searchString OR lName LIKE #searchString OR zip LIKE #searchString OR email LIKE #searchString OR cwaSource LIKE #searchString OR length LIKE #searchString OR price LIKE #searchString ORDER BY #orderByString";
Configuration rootWebConfig = System.Web.Configuration.WebConfigurationManager.OpenWebConfiguration("/Cabot3");
ConnectionStringSettings connectionString = rootWebConfig.ConnectionStrings.ConnectionStrings["secureodb"];
// Create an SqlConnection to the database.
using (SqlConnection connection = new SqlConnection(connectionString.ToString()))
using (SqlCommand _fillDatabase = new SqlCommand(updateCommand, connection))
{
connection.Open();
_fillDatabase.Parameters.Add("#searchString", SqlDbType.VarChar, 50).Value = _searchString;
_fillDatabase.Parameters.Add("#orderByString", SqlDbType.VarChar, 50).Value = _orderByString;
_fillDatabase.ExecuteNonQuery();
dataAdapter = new SqlDataAdapter("SELECT * FROM SecureOrders", connection);
// create the DataSet
dataSet = new DataSet();
// fill the DataSet using our DataAdapter
dataAdapter.Fill(dataSet, "SecureOrders");
DataView source = new DataView(dataSet.Tables[0]);
DefaultGrid.DataSource = source;
DefaultGrid.DataBind();
connection.Close();
}
}
Form
<form id="form1" runat="server">
<asp:ScriptManager ID = "ScriptManager" runat="server" />
<div>
<asp:Label runat="server" id = "orderByLabel" Text = "Order By: " />
<asp:DropDownList runat="server" ID="orderByList" AutoPostBack="true">
<asp:ListItem Value="fName" Selected="True">First Name</asp:ListItem>
<asp:ListItem Value="lName">Last Name</asp:ListItem>
<asp:ListItem Value="state">State</asp:ListItem>
<asp:ListItem Value="zip">Zip Code</asp:ListItem>
<asp:ListItem Value="cwaSource">Source</asp:ListItem>
<asp:ListItem Value="cwaJoined">Date Joined</asp:ListItem>
</asp:DropDownList>
</div>
<div>
<asp:Label runat="server" ID="searchLabel" Text="Search For: " />
<asp:TextBox ID="searchTextBox" runat="server" Columns="30" />
<asp:Button ID="searchButton" runat="server" Text="Search" />
</div>
<div>
<asp:UpdatePanel ID = "up" runat="server">
<ContentTemplate>
<div style= "overflow:auto; height:50%; width:100%">
<asp:GridView ID="DefaultGrid" runat = "server" DataKeyNames = "IdentityColumn"
onselectedindexchanged = "DefaultGrid_SelectedIndexChanged"
autogenerateselectbutton = "true">
<SelectedRowStyle BackColor="Azure"
forecolor="Black"
font-bold="true" />
<Columns>
<asp:TemplateField HeaderText="Processed">
<ItemTemplate>
<asp:CheckBox ID="CheckBoxProcess" AutoPostBack = "true" Checked ='<%#Eval("processed") %>' OnCheckedChanged="CheckBoxProcess_CheckedChanged" runat="server" Enabled="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
</div>
<div style= "overflow:auto; height:50%; width:100%" />
<table border="1">
<tr>
<td>Name: </td>
<td><%=name %></td>
</tr>
<tr>
<td>Zip: </td>
<td><%=zip %></td>
</tr>
<tr>
<td>Email: </td>
<td><%=email %></td>
</tr>
<tr>
<td>Length: </td>
<td><%=length %></td>
</tr>
<tr>
<td>Price: </td>
<td><%=price %></td>
</tr>
<tr>
<td>Source: </td>
<td><%=source %></td>
</tr>
</table>
</div>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>

I have never used the UpdatePanel since my company uses Telerik, but from the examples I see during my research I remember seeing a trigger component.
From my understanding, if the control is w/i the UpdatePanel itself, then you do not have to specify the trigger, since it is assumed.
For your scenario, the trigger (dropdownlist) is outside of the UpdatePanel. You may need to include this in your aspx:
<asp:UpdatePanel ID = "up" runat="server">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="orderByList" >
</Triggers>
<ContentTemplate>
...

Try the following:
In HTML move the update panel direct after the scriptmanager line.
Move the code lines in vieworders_PreInit to vieworders_PageLoad with !IsPostPack clause.

Related

Hide EmptyDataTemplate but leave header visible

I have an EmptyDataTemplate on my ASP.NET webform which allows users to add a record to the database. Depending on the permissions of the user, this EmptyDataTemplate needs to be visible and hidden if no data is found (I have this working!)
For example, my user has Read Access only. When they search a specific criteria, no results are displayed they cannot see the EmptyDataTemplate. However, if they search a criteria, and there is data, data is displayed WITHOUT the headers.
Can someone please help explain why this is happening and if there's a way around it?
The headers are HeaderText on TemplateFields.
I'm hoping it's a general trick.
Thank you in advance for your help!
Please note, it's the HeaderText in the TemplateFields I want to display- not the in the emptyDataTemplate as they'll head up the columns of data that match the search criteria.
edit: code added as requested
For hiding the EmptyDataTemplate:
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
Export_All.Visible = true;
}
else if (userManagement.getMIFReadWriteAccess() == "Write")
{
control.Visible = true;
Export_All.Visible = true;
}
}
in markup for the header text (i've only shown one column but the markup is the same for all of them)
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:Label ID="lbl_Index" runat="server" Text='<%#Eval("id") %>'></asp:Label>
<asp:Label ID="lbl_ID" runat="server" Text="" Visible="false"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
EmptyDataTemplate:
<EmptyDataTemplate>
<div id="emptyData" runat="server">
<tr>
<th></th>
<th>Serial Number</th>
<th>Comments</th>
<th>Review Date</th>
<th>Approved By</th>
</tr>
<tr>
<td>
<asp:Button runat="server" ID="btInsert" Text="In" OnClick="Add" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
<br />
<asp:Button runat="server" ID="btInsertOut" Text="Out" OnClick="AddOut" CommandName="EmptyDataTemplate" Class="Button" OnClientClick="return confirm('You are about to confirm this action. Please confirm this action by clicking OK. If you do not wish to do this, please select Cancel.');" />
</td>
<td>
<asp:TextBox runat="server" ID="tb_Serial_Number" CssClass="text"></asp:TextBox>
</td>
<td>
<asp:TextBox ID="tb_comments" Width="100%" MaxLength="50" runat="server" placeholder="max 50 characters"/>
</td>
<td>
<asp:TextBox ID="tb_reviewDate" runat="server" DataFormatString="{0:dd/mm/yyyy}" Text='<%#Eval("review_by") %>'></asp:TextBox>
</td>
<td><asp:DropDownList ID="tb_approved_by" runat="server">
</asp:DropDownList> </td>
</tr>
</div>
</EmptyDataTemplate>
After trial and error, I found that programatically adding a header row in C# did the trick. Probably not the best way of doing it, but it worked.
Code is as follows:
#region show the emptyDataTemplate depending on user rights
Control control = null;
control = GridView1.Controls[0].Controls[0];
if (userManagement.getMIFReadWriteAccess() == "Read")
{
control.Visible = false;
GridViewRow HeaderRow = new GridViewRow(1, 0, DataControlRowType.Header, DataControlRowState.Insert);
TableCell HeaderCell2 = new TableCell();
HeaderCell2.Text = "Country";
HeaderCell2.ColumnSpan = 1;
HeaderRow.Cells.Add(HeaderCell2);
//Repeat the above for every column of data you have!
GridView1.Controls[0].Controls.AddAt(0, HeaderRow);

Update SSRS report parameters using custom ASP.NET controls

I have a ASP.NET web app, which uses SSRS 2008 R2 on another machine in Native mode. The app has a page for generation reports created in SSRS.
I use my own custom controls for report parameters. After all the parameters are set, the page generates the report using a hidden ReportViewer control.
Here is the page layout:
<asp:Repeater ID="rptParameters" runat="server">
<ItemTemplate>
<tr>
<td class="label">
<asp:Literal ID="label" runat="server"/>:
</td>
<td class="control">
<asp:TextBox ID="tbx" runat="server" Visible="false"/>
<my:tsJCalendar ID="calendar" runat="server" GeneratePostback="false" HasValidation="true" ErrorDisplay="None" CompareMessage="Date must be in valid 'mm/dd/yyyy' format!" Visible="false"/>
<asp:RadioButtonList ID="radioList" runat="server" Visible="false"
RepeatDirection="Horizontal" RepeatLayout="Flow">
<asp:ListItem Text="True" Value="1"></asp:ListItem>
<asp:ListItem Text="False" Value="0"></asp:ListItem>
</asp:RadioButtonList>
<asp:DropDownList ID="ddl" runat="server" Visible="false"></asp:DropDownList>
<asp:HiddenField ID="hdnForDdl" runat="server"/>
</td>
<td width="22px"></td>
</ItemTemplate>
<AlternatingItemTemplate>
<td class="label">
<asp:Literal ID="label" runat="server"/>:
</td>
<td class="control">
<asp:TextBox ID="tbx" runat="server" Visible="false"/>
<my:tsJCalendar ID="calendar" runat="server" GeneratePostback="false" HasValidation="True" ErrorDisplay="None" CompareMessage="Date must be in valid 'mm/dd/yyyy' format!" Visible="false"/>
<asp:RadioButtonList ID="radioList" runat="server" Visible="false">
<asp:ListItem Text="True" Value="1"></asp:ListItem>
<asp:ListItem Text="False" Value="0"></asp:ListItem>
</asp:RadioButtonList>
<asp:DropDownList ID="ddl" runat="server" Visible="false"></asp:DropDownList>
<asp:HiddenField ID="hdnForDdl" runat="server"/>
</td>
</tr>
</AlternatingItemTemplate>
</asp:Repeater>
<rsweb:ReportViewer ID="rvReports" runat="server" Width="100%"
ShowReportBody="False" ShowPromptAreaButton="false" ShowWaitControlCancelLink="false"
AsyncRendering="false" Visible="false">
</rsweb:ReportViewer>
<hr />
<asp:Button ID="btnRun" runat="server" Text="Run Report" />
To generate custom parameter controls I use the repeater and show an appropriate control according by the report parameter type.
I am working with SSRS using its ReportingService2005 webservice. E.g. on the first page loading, I am getting report parameters using this code:
Private Function GetParameterReports(values As ParameterValue()) As ReportParameter()
Dim rs As New ReportingService2005()
rs.Credentials = New MyReportCredentials().NetworkCredentials
Dim forRendering As Boolean = True
Dim historyID As String = Nothing
Dim credentials As DataSourceCredentials() = Nothing
Dim paramInfos As ReportParameter() = rs.GetReportParameters(ReportPath, historyID, forRendering, values, credentials)
Return paramInfos
End Function
The 'values' parameter is Nothing for the first time. However, if a parameter depends on other parameters, I do a postback, and pass report values to the report to get updated parameters, using the same GetParameterReports() method.
All the reports have a special field, 'user_id', which is the identifier of the logged in user. I must set this parameter manually in the code, and I am trying to do this by using 2 ways:
Dim Values As New List(Of ParameterValue)()
Dim singleUserParameter As New ParameterValue()
With singleUserParameter
.Name = "user_id"
.Value = Security.CurrentUserPeopleID
End With
Values.Add(singleUserParameter)
paramInfos = GetParameterReports(Values.ToArray)
and
Dim userIdParameter As New ReportParameter()
userIdParameter.DefaultValues = New String() {Security.CurrentUserPeopleID.ToString()}
userIdParameter.PromptUser = False
Dim rs As New ReportingService2005()
rs.Credentials = New MyReportCredentials().NetworkCredentials
rs.SetReportParameters(ReportPath, paramInfos)
paramInfos = GetParameterReports(Nothing)
Some of the report parameters depend on the 'user_id', but, unfortunately, after calling ReportingService2005.GetReportParameters() with the passed 'user_id' value, dependent parameters still don't have DefaultValues.
Could you help to understand whether I am doing something wrong while setting the report parameters values, or the reason is in how the SSRS report was created?

Do a Button Click from Code behide

I have a gridview which lists Tools and Access values. To edit I have an edit imagebutton on each row. I have an OnRowBound method which assigns an OnClick attribute to each button so that I will know which record I need to edit.
The code is
Protected Sub ChangeFirstRowIcon(ByVal Sender As Object, ByVal e As GridViewRowEventArgs) Handles gv_AccessRights.RowDataBound
'This sub fires on each gridview row created...
'It first checks that the row is a data row (as opposed to Header, Footer etc.)
'If ib_Edit is true then change add an attribut to button with aid, tid and ac values attached.
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ib_Edit As ImageButton = e.Row.FindControl("ib_Edit")
Dim lb_AccessID As Label = e.Row.FindControl("lb_AccessID")
Dim hd_ToolID As HiddenField = e.Row.FindControl("hd_ToolID")
Dim hd_AccessCode As HiddenField = e.Row.FindControl("hd_AccessCode")
If ib_Edit IsNot Nothing Then
ib_Edit.Attributes.Add("onClick", "proxyClick('" & lb_AccessID.Text & "', '" & hd_ToolID.Value & "', '" & hd_AccessCode.Value & "')")
End If
End If
End Sub
I'm using a hidden proxy button to show a modal popup which the user will use to edit a record... (the same popup will be used to add a new access record... but that will come later). So having passed my details to proxyClick I set values to controls within the modal popup. The javascript is....
<script type="text/javascript">
function proxyClick(aid, tid, ac) {
document.getElementById('hd_AccessID').value = aid;
document.getElementById('hd_ToolIDMod').value = tid;
document.getElementById('hd_AccessCodeMod').value = ac;
document.getElementById('but_SetModalDetails').click();
}
</script>
For reference the main bits of the markup are....
<table class="border">
<tr>
<td>
<asp:Button ID="but_SetModalDetails" runat="server" Style="display: none" Text="Set modal details" ClientIDMode="Static" UseSubmitBehavior="true" />
<asp:Button ID="but_HiddenProxy" runat="server" Style="display: none" Text="Hidden Proxy Button for Modal Popup" ClientIDMode="Static" />
</td>
<td class="rt">
<asp:Button ID="but_AddTool" runat="server" AccessKey="A" CssClass="butGreen" Text="Add Tool" ToolTip="Add Tool - Alt A" />
</td>
</tr>
</table>
<asp:ModalPopupExtender ID="mpx_AddEditAccess" runat="server" CancelControlID="but_Cancel"
BehaviorID="pn_AddEditAccess" PopupControlID="pn_AddEditAccess" TargetControlID="but_HiddenProxy"
BackgroundCssClass="modalBackground" />
<asp:Panel ID="pn_AddEditAccess" runat="server" Width="500px" CssClass="modalPopup"
Style="display: block">
<div class="box">
<h2>
<asp:Label ID="lb_ModTitle" runat="server"></asp:Label>
</h2>
<asp:HiddenField ID="hd_AccessID" runat="server" ClientIDMode="Static"></asp:HiddenField>
<div class="block">
<asp:UpdatePanel ID="up_Access" runat="server" UpdateMode="Always">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddl_ToolName" EventName="SelectedIndexChanged" />
</Triggers>
<ContentTemplate>
<table>
<tr>
<th class="p66 rt">
Tool Name:
</th>
<td class="p66">
<asp:HiddenField ID="hd_ToolIDMod" runat="server" ClientIDMode="Static" />
<asp:DropDownList ID="ddl_ToolName" runat="server" AutoPostBack="true" AppendDataBoundItems="True"
DataSourceID="SqlDS_Tools" DataTextField="ToolName" DataValueField="ToolID" OnSelectedIndexChanged="ddl_ToolName_SIC">
<asp:ListItem Text="Please Select..." Value="0"></asp:ListItem>
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDS_Tools" runat="server" ConnectionString="<%$ ConnectionStrings:ToolsConnString %>"
SelectCommand="SELECT [ToolID], [ToolName] FROM [tbl_Tools] WHERE ([Redundant] = #Redundant)">
<SelectParameters>
<asp:Parameter DefaultValue="False" Name="Redundant" Type="Boolean" />
</SelectParameters>
</asp:SqlDataSource>
<asp:RequiredFieldValidator ID="rfv_ddl_ToolName" runat="server" ControlToValidate="ddl_ToolName"
CssClass="error" Display="Dynamic" ErrorMessage="Please Select Tool Name" InitialValue="0">
</asp:RequiredFieldValidator>
</td>
</tr>
<tr>
<th class="p66 rt">
Access Rights:
</th>
<td class="p66">
<asp:HiddenField ID="hd_AccessCodeMod" runat="server" ClientIDMode="Static" />
<asp:DropDownList ID="ddl_AccessCode" runat="server" Enabled="false">
<asp:ListItem Text="No Access" Value="0"></asp:ListItem>
</asp:DropDownList>
</td>
</tr>
<tr>
<td class="p66">
<asp:Button ID="but_Cancel" runat="server" Text="Cancel" />
</td>
<td class="p66 rt">
<asp:Button ID="but_Save" runat="server" Text="Save" />
</td>
</tr>
</table>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</div>
</asp:Panel>
As you can see I have implemented two hidden buttons but_SetModalDetails and but_HiddenProxy. but_SetModalDetails has some codebehind which sets a couple of dropdown lists (one populated from a datasource, the other is populated dynamically based on the value of the first. The codebehind is...
Protected Sub but_SetModalDetails_Click(ByVal sender As Object, ByVal e As EventArgs) Handles but_SetModalDetails.Click
If hd_AccessID.Value = "0" Then
lb_ModTitle.Text = "Assigning Access Rights to:"
ddl_ToolName.SelectedIndex = 0
ddl_AccessCode.SelectedIndex = 0
ddl_AccessCode.Enabled = False
Else
lb_ModTitle.Text = "Edit Access Rights to:"
ddl_ToolName.SelectedValue = hd_ToolIDMod.Value
ddl_ToolName.Enabled = False
SqlStr = "SELECT AccessID AS ddlValue, AccessText as ddlText FROM tbl_AccessCodes WHERE ToolID = " & hd_ToolIDMod.Value
PopulateDDLvalue(ddl_AccessCode, SqlStr)
ddl_AccessCode.SelectedValue = hd_AccessCodeMod.Value
ddl_AccessCode.Enabled = True
End If
'NOW I NEED TO SIMULATE but_HiddenProxy Click
End Sub
As you can see at the end I need to simulate a click of but_HiddenProxy so that the modalPopup is shown populated with the correct data.
Any Ideas? Thanks
After all that... I was able to do everything in codebehind...
I only needed one hidden button but_HiddenProxy.
In the gridview instead of setting an onClick attribute for each edit image button I just set a commandname of 'AccessEdit' (don't use 'Edit'). I then had a method that handled the gridview.RowCommand event. This found the various info I needed by using findControl on the selected row. These values were then used to populate the dropdowns in the popup and then use the show command to make the popup visible.
One bit that did stump me for a while was why my RowCommand was not triggering when an imagebutton was clicked. I'd forgotten that I had validation in the modal which stopped the RowCommand being executed. I stuck a CausesValidation="false" in the imagebutton and all was OK.
Talk about using a hammer to crack a nut!

Update Panel & Event firing twice

I have an ASPX page with 3 dropdown boxes via Infragistic controls. 1 of them is inside an UpdatePanel and the two outside of the UpdatePanel is suppose to control what is displayed in the 3rd one via AsynPostBack Event. Both dropdown boxes outside of the UpdatePanel call the same function in the code behind but depending on which object I pass to it, it will show something in the 3rd drop-down box. Problem is, the function appears to be getting triggered twice regardless of which dropdown box I select and each call passes its control to the function and the second one is what always being displayed even when I click on the first one. How do I stop that? I'm expecting for the function to just fire once depending on which control I select. I also tried to have each dropdown box point to its own function and still, both of them got triggered...
<td style="width:3px;"><asp:HiddenField ID="pnb_recno" runat="server" /></td>
<td style="width:100px;">Line Of Business:</td>
<td colspan="2" width="150px"><!--OnSelectionChanged="pnb_product_list"-->
<ig:WebDropDown ID="pnb_ddRgn" runat="server" Width="175px" DropDownContainerHeight="100px"
EnableDropDownAsChild="false" TextField="Name" DropDownContainerWidth="175px" Font-Size="11px"
StyleSetName="Windows7" OnSelectionChanged="pnb_product_list" AutoPostBack="true" ClientEvents-SelectionChanged="pnb_chgLOB" >
<Items>
<ig:DropDownItem Text="" Value="" />
<ig:DropDownItem Text="Global Client Access" Value="Global Client Access" />
<ig:DropDownItem Text="Solution Center" Value="Solution Center" />
<ig:DropDownItem Text="Both" Value="Both" />
</Items>
</ig:WebDropDown>
</td>
<td style="width:3px;"></td>
<td style="width:100px;">Problem Type:</td>
<td colspan="2" width="150px">
<ig:WebDropDown ID="pnb_ddPblmTyp" runat="server" Width="175px" DropDownContainerHeight="80px" EnableDropDownAsChild="false" TextField="Name" DropDownContainerWidth="175px" Font-Size="11px" StyleSetName="Windows7" AutoPostBack="true" OnSelectionChanged="pnb_product_list">
<Items>
<ig:DropDownItem Text="" Value="" />
<ig:DropDownItem Text="Infrustructure" Value="Infrustructure" />
<ig:DropDownItem Text="Products" Value="Products" />
</Items>
</ig:WebDropDown>
</td>
<td colspan="2" width="150px">
<asp:UpdatePanel ID="pnb_udtPnlPrdts" runat="server" UpdateMode="Conditional">
<Triggers>
<asp:AsyncPostBackTrigger ControlID="pnb_ddRgn" EventName="SelectionChanged" />
<asp:AsyncPostBackTrigger ControlID="pnb_ddPblmTyp" EventName="SelectionChanged" />
</Triggers>
<ContentTemplate>
<ig:WebDropDown ID="pnb_ddPrdts" runat="server" Width="175px" EnableClosingDropDownOnSelect="false" TextField="ProductName" EnablePaging="false" DropDownContainerHeight="175px" EnableMultipleSelection="true" MultipleSelectionType="Checkbox" StyleSetName="Windows7" DisplayMode="DropDown">
<ClientEvents SelectionChanged="selectedIndexChanged" SelectionChanging="selectedIndexChanging" />
</ig:WebDropDown>
</ContentTemplate>
</asp:UpdatePanel>
</td>
protected void pnb_product_list(object sender, EventArgs e)
{
try
{
using (SqlConnection sqlConnection = new SqlConnection(connectionString))
{
using (SqlCommand sqlCommand = new SqlCommand("dbo.getDdProducts", sqlConnection))
{
sqlCommand.CommandTimeout = 0;
sqlCommand.CommandType = CommandType.StoredProcedure;
if (!String.IsNullOrEmpty(pnb_ddRgn.CurrentValue))
sqlCommand.Parameters.AddWithValue("#lob", pnb_ddRgn.CurrentValue);
else
sqlCommand.Parameters.AddWithValue("#alert_type", pnb_ddPblmTyp.CurrentValue);
using (DataTable dataTable = new DataTable())
{
using (SqlDataAdapter dataAdapter = new SqlDataAdapter(sqlCommand))
{
dataAdapter.Fill(dataTable);
}
pnb_ddPrdts.DataSource = dataTable;
pnb_ddPrdts.DataBind();
}
}
}
}
catch (Exception exception)
{
}
}
I would try looking for AutoPostBackFlags one for selectionChanged and another for valueChanged is it possible it is just infact because both these events are being triggered is why it is posting back twice??

Format data in Repeater

The result of a stored procedure will look like this.
1 Group Admin user1
1 Group Admin user2
1 Group Admin user3
1 Group Admin user4
1 Group Admin user5
2 Group Second user6
2 Group Second user7
2 Group Second user8
2 Group Second user9
2 Group Second user10
2 Group Second user11
I want to format the data as shown in picture .
The question is related with this
I think Repeater is the best control to use here. What you think ? If so, how can I format it ?
Is GridView with row merging a good idea ?
After reading the answer
// Page_Load
DataSet ds = GetAllUsers();
ViewState["UserRoles"] = ds;
rptParent.DataSource = ds;
rptParent.DataBind();
Other events
// ItemDataBound
protected void rptParent_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if ((item.ItemType == ListItemType.Item) ||
(item.ItemType == ListItemType.AlternatingItem))
{
string s = e.Item.DataItem.ToString();
string roleID = ((HiddenField)e.Item.FindControl("hidRoleId")).Value;
Repeater childRepeater = (Repeater)item.FindControl("rptChild");
string filterExp = "RoleId=" + roleID;
DataTable dtChild = ((DataSet)ViewState["UserRoles"]).Tables[0];
DataRow[] dr = dtChild.Select(filterExp);
childRepeater.DataSource = dr;
childRepeater.DataBind();
}
}
Mark up
// MarkUp
<asp:Repeater runat="server" ID="rptParent" OnItemDataBound="rptParent_ItemDataBound">
<ItemTemplate>
<table>
<tr>
<td>
<asp:HiddenField ID="hidRoleId" runat="server" Value='<%#Eval("RoleId")%>' />
<asp:Label ID="lblRoleName" runat="server" Text='<%#Eval("RoleName")%>'></asp:Label>
</td>
<td>
<asp:CheckBox ID="CheckBox4" runat="server" />
</td>
<td>
<asp:CheckBox ID="CheckBox5" runat="server" />
</td>
<td>
<asp:CheckBox ID="CheckBox6" runat="server" />
</td>
</tr>
</table>
<asp:Repeater ID="rptChild" runat="server">
<ItemTemplate>
<table>
<tr>
<td>
<asp:HiddenField ID="hidRoleId" runat="server" Value='<%#Eval("UserId")%>' />
<asp:Label ID="Label2" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "UserName") %>'></asp:Label>
</td>
<td>
<asp:CheckBox ID="CheckBox7" runat="server" />
</td>
<td>
<asp:CheckBox ID="CheckBox8" runat="server" />
</td>
<td>
<asp:CheckBox ID="CheckBox9" runat="server" />
</td>
</tr>
</table>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
I get the following output
But the Group name is also repeating :(. This is NOT what I want
I would use a nested repeater.
With Linq you can easily group your data and bind this to the outer repeater (and set the values for the 3 top checkboxes) and then the OnDataBound of the outer repeater can set the User list as datasource for the nested repeater.
Markup would look like:
<asp:Repeater runat="server" ID="ParentRepeater" OnItemDataBound="ParentRepeater_ItemDataBound">
<ItemTemplate>
// Markup for the three top checkboxes
<asp:Repeater runat="server" ID="ChildRepeater">
<ItemTemplate>
// Inner layout for each user with checkboxes
</ItemTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>
And in the code behind:
protected void ParentRepeater_ItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if ((item.ItemType == ListItemType.Item) ||
(item.ItemType == ListItemType.AlternatingItem))
{
var data = item.DataItem as <YourType>;
Repeater childRepeater = (Repeater)item.FindControl("ChildRepeater");
childRepeater .DataSource = data.<InnerResults>;
childRepeater .DataBind();
}
}
If you need to use an anonymous type for your grouping have a look at the Tuple<,> class. That can help if you want to cast the item.DataItem back to a known type.

Resources