pass a sql parameter into a dynamically created user control C# - c#

I created a gridview user control with a sqldatasource calling a stored procedure. The user control is dynamically created on the aspx page and I have everything working without passing any parameters in. I cannot figure out how to pass the parameters in the user control. Here is a minimized version of the code.
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="Survey.ascx.cs" Inherits="AppSurvey" %>
<asp:GridView ID="GridView1" runat="server">
<Columns>
<asp:TemplateField HeaderText="Count" HeaderStyle-HorizontalAlign="center" ItemStyle-HorizontalAlign="center">
<ItemTemplate>
<asp:TextBox ID="txtAnswerCount" runat="server" Columns="5" MaxLength="5" />
<asp:RegularExpressionValidator ID="RegularExpressionValidator1" runat="server" ValidationExpression="^\d+$"
Display="None" SetFocusOnError="true" ControlToValidate="txtAnswerCount" ErrorMessage = "Count values must be entered as integer values." />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" CancelSelectOnNullParameter="false" ConnectionString="<%$ ConnectionStrings:1316 %>" SelectCommand="dbo.usp_Survey" SelectCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="Category" Type="String" />
</SelectParameters>
</asp:SqlDataSource>
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Threading;
using System.Web;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Configuration;
namespace EUCNET01316
{
public partial class Survey : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
SqlDataSource1.SelectParameters["Category"].DefaultValue = ?????;
GridView1.DataSourceID = "SqlDataSource1";
GridView1.DataBind();
}
}
}
**** ASPX Page
protected void Page_Load(object sender, EventArgs e)
{
UserControl ctl = Page.LoadControl("Survey.ascx") as UserControl;
Panel PB = new Panel();
PB.Controls.Add(ctl);
}

There are a lot of ways to do this, but this is one... In your user control's codebehind you can create a public property to accept your parameter or the value that you will assign to your sql parameter:
namespace EUCNET01316
{
public partial class Survey : System.Web.UI.UserControl
{
protected void Page_Load(object sender, EventArgs e)
{
SqlDataSource1.SelectParameters["Category"].DefaultValue = MyParameterValue;
GridView1.DataSourceID = "SqlDataSource1";
GridView1.DataBind();
}
public string MyParameterValue {get;set;}
}
}
Then in your ASPX page markup, add a directive to reference to the user control:
<%# Reference Control="~/Usercontrols/Survey.ascx" %>
Then in the codebehind, cast your user control as its type instead of just "UserControl"
Survey ctl = Page.LoadControl("Survey.ascx") as Survey;
// set the property
ctl.MyParameterValue = "foo";
Now in your codebehind you can set the property you created on your user control. Just make sure you set the property BEFORE attempting to load the control into the page's control collection (at which point the lifecycle will try to "catch up," and your control's page_load will fire prior to the property being set).

Related

C# Roles.GetAllRoles() error - does not contain a definition

I am trying to get all Roles in my C# application.
When I copy the C# code from: https://learn.microsoft.com/en-us/dotnet/api/system.web.security.roles.getallroles?view=netframework-4.8
into a single aspx page exactly as they have the example then the page works and I can see the Roles and add one properly.
When I have the following code-behind code:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Security;
namespace ToolingPMv2.Admin.Access
{
public partial class Roles : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string[] rolesArray;
rolesArray = Roles.GetAllRoles();
RolesGrid.DataSource = rolesArray;
RolesGrid.DataBind();
}
}
}
}
My aspx page:
<%# Page Language="C#" AutoEventWireup="true" MasterPageFile="~/Site.Master" CodeBehind="UserRoles.aspx.cs" Inherits="ToolingPMv2.Admin.Access.Roles" %>
<asp:Content ID="Content1" ContentPlaceHolderID="MainContent" runat="server">
<h2>Roles</h2>
<br />
<asp:GridView runat="server" CellPadding="2" id="RolesGrid" Gridlines="Both" CellSpacing="2" AutoGenerateColumns="false" >
<HeaderStyle BackColor="navy" ForeColor="white" />
<Columns>
<asp:TemplateField HeaderText="Roles" >
<ItemTemplate>
<%# Container.DataItem.ToString() %>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Content>
I get the following error: 'ToolingPMv2.Admin.Access.Roles' does not contain a definition for 'GetAllRoles'
I thought that if I have 'Using System.Web.Security' I could access this method.
What am I doing wrong? This seems like a basic fundamental lesson that I should know by now.
The class for your page is named Roles so that is hiding the one in the other namespace. You need to be explicit, for example:
rolesArray = System.Web.Security.Roles.GetAllRoles();

GridView RowDataBoundEvent not running

I'm working with a GridView and I am using a TableAdapter to communicate with my SQL Server 2017 Express. I have managed to display the table into a GridView but I would like to make the name of each entry in my database have a hyperlink that will direct the user to another page that contains a DetailsView that would allow the user to edit the corresponding entry. However, I am currently have troubles with the RowDataBoundEvent as it seemingly is not triggering.
When I set a breakpoint right at the if statement, the program does not stop at the breakpoint.
protected void ProductViewRowBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
string hyperLink = e.Row.Cells[1].Text;
e.Row.Cells[1].Text = "Test";
//HyperLink link = new HyperLink;
}
}
I checked my RowDataBound method name and it matches the one I specified in the aspx file:
<asp:GridView ID="ProductView" runat="server" Height="299px" Width="578px" AllowPaging="True" HorizontalAlign="Center"
OnRowDataBoundEvent="ProductViewRowBound" style="table-layout:auto">
<HeaderStyle Width="300px" />
</asp:GridView>
CS File:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Data;
public partial class Maintenance : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
DataTable dt = new DataTable();
ProductSetTableAdapters.Product_Table_AlphaTableAdapter productAdapter = new ProductSetTableAdapters.Product_Table_AlphaTableAdapter();
ProductView.DataSource = productAdapter.GetData();
ProductView.DataBind();
}
ProductView.RowDataBound += new GridViewRowEventHandler(ProductViewRowBound);
}
protected void ProductViewRowBound(object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
string hyperLink = e.Row.Cells[1].Text;
e.Row.Cells[1].Text = "Test";
//HyperLink link = new HyperLink;
}
}
}
ASPX File:
<%# Page Title="" Language="C#" MasterPageFile="~/MasterPage.master" AutoEventWireup="true" CodeFile="Maintenance.aspx.cs" Inherits="Maintenance" %>
<asp:Content ID="Content1" ContentPlaceHolderID="head" Runat="Server">
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="ContentPlaceHolder1" Runat="Server">
<div style="overflow-x:scroll;overflow-y:scroll; margin-left:auto; margin-right:auto;">
<asp:GridView ID="ProductView" runat="server" Height="299px" Width="578px" AllowPaging="True" HorizontalAlign="Center"
OnRowDataBoundEvent="ProductViewRowBound" style="table-layout:auto">
<HeaderStyle Width="300px" />
</asp:GridView>
</div>
</asp:Content>
Why is my RowDataBoundEvent not running and what can I do to fix it?
First, OnRowDataBoundEvent does not exist. It should be OnRowDataBound in the GridView.
<asp:GridView ID="ProductView" runat="server" OnRowDataBound="ProductViewRowBound">
Next you are binding the correct method to the GridView from code behind, but AFTER you bind data to the GridView. So it will not work when you bind productAdapter.GetData().
So either set the correct event name in the GridView aspx or move the method binding above ProductView.DataBind();

Simple ASP.NET File Upload

I have a very simple ASP.NET page that uploads an Excel workbook, then processes it. It uses AJAXFILEUPLOAD from the AJAX toolkit on ASP.NET... Here's the markup:
<%# Page Title="" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true"
CodeBehind="ImportWorkbook.aspx.cs" Inherits="Timesheet.ImportWorkbook" %>
<asp:Content ID="Content1" runat="server" ContentPlaceHolderID="HeaderContentPlaceHolder">
<h1 class="topContent">
Upload CPAS Timesheet Workbooks
</h1>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="RightContentPlaceHolder" runat="server">
<br />
<br />
<asp:HiddenField ID="tbTSID" runat="server" />
<asp:HiddenField ID="tbWorkbookPath" runat="server" />
<ajaxToolkit:AjaxFileUpload ID="AjaxFileUpload1" runat="server" AllowedFileTypes="xls,xlsx,xlsm"
CssClass="dropdown" MaximumNumberOfFiles="1" OnUploadComplete="AjaxFileUpload1_UploadComplete" />
<br />
<br />
<asp:Panel ID="ProcessChoices" runat="server" >
<br />
<br />
<p>
Select how you want this workbook processed:</p>
<br />
<asp:RadioButtonList ID="rbChoices" runat="server" BorderStyle="Groove" BorderWidth="2px"
BorderColor="Black" BackColor="Teal" Font-Names="Tahoma" Font-Size="10pt" ForeColor="White"
Width="40%">
<asp:ListItem Value="True" Selected="True">&nbsp Replace ALL Items in the Timesheet</asp:ListItem>
<asp:ListItem Value="False">&nbsp Add Items from this Workbook to the Existing Timesheet Items</asp:ListItem>
</asp:RadioButtonList>
<br />
<br />
<asp:Button ID="btnValidate" runat="server" Text="Validate and Process"
BackColor="#B92217" ForeColor="White" BorderColor="#7C1810"
BorderStyle="Groove" Font-Names="Tahoma" onclick="btnValidate_Click" />
</asp:Panel>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="BottomSpanContentPlaceHolder" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
</asp:Content>
The master page and css pages are trivial, formatting only.
Here's the codebehind:
using System;
using System.IO;
using TimesheetUtilites;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using AjaxControlToolkit;
namespace Timesheet
{
public partial class ImportWorkbook : System.Web.UI.Page
{
private const string HDriveLocation= "H:\\mtv\\secure\\Construction\\Access\\CPAS WorkArea\\TimesheetUploads\\";
private string strWorkbookPath;
private int currTSID;
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
if (Request.QueryString["ID"] != null)
{
tbTSID.Value = Request.QueryString["ID"]; // Storing the Timesheet ID in a hidden Textbox
}
}
else
{
if (!string.IsNullOrEmpty(tbWorkbookPath.Value))
{
ProcessChoices.Enabled = true;
}
}
int.TryParse(tbTSID.Value, out currTSID);
strWorkbookPath = tbWorkbookPath.Value;
}
protected void AjaxFileUpload1_UploadComplete(object sender, AjaxFileUploadEventArgs e)
{
strWorkbookPath = HDriveLocation + Path.GetFileName(e.FileName);
tbWorkbookPath.Value = strWorkbookPath;
AjaxFileUpload1.SaveAs(strWorkbookPath);
ProcessChoices.Enabled = true;
}
protected void btnValidate_Click(object sender, EventArgs e)
{
bool processOption;
bool.TryParse(rbChoices.SelectedValue, out processOption);
strWorkbookPath = tbWorkbookPath.Value;
TimesheetUtilites.ImportTimesheet imp = new ImportTimesheet(currTSID, strWorkbookPath, processOption);
}
}
}
My issue is simple. Although the event handler "AjaxFileUpload1_UploadComplete" works fine, and uploads the file in an instant, when I fire the "btnValidate_Click" event, the "tbWorkbookPath.Value" has become an empty string, and the "ProcessChoices.Enabled" propety doesn't change. Needless to say, the "Upload Complete" event handler is the only opportunity I have to capture this file path, so I'm at a loss what I'm doing wrong.
I posted on ASP.NET and go NO answers. Can anyone give me an idea where to start?
This is information you should be storing in your page's ViewState so that it persists between postbacks and resets on page initialization. Change your private string member to something like the following:
private string strWorkbookPath {
get {
return this.ViewState["strWorkbookPath"];
}
set {
this.ViewState["strWorkbookPath"] = value;
}
}
If you need a primer on what the ViewState is, check out this article on MSDN: Saving Web Forms Page Values Using View State. It's a bit dated but still communicates the basics of how ViewState operates currently.
Put a hidden field with runat="server" attribute on your page and use the below script:
<script type="text/javascript">
function uploadComplete(sender, args) {
var filename = args.get_fileName();
$("#hiddden_field_id").val(filename);
}
</script>
Now you should be getting the image name in your events.
I think you should try storing that value in session rather than a hidden field as the page is not reloaded and it was an ajax call. So when the button is clicked for validation, it is actually another request made but the value of the hidden field in this page object and the hidden field is still empty. Once your job is done for that value in session, remove it from there or set it to some different value.

AsyncPostBackTrigger Just flashing/flicking the UpdatePanel but not updating it

I am trying UpdatePanel & AsyncPostBackTrigger on master pages through find control method but problem is when I click on button (UpdateButton) It just flash/flick (No Postback) the UpdatePanle but still it don't update or refresh the gridview (images) inside the updatePanel.
I have placed script Manger on the master page & an AJAX Update panel in a ContentPlaceHolder in the child page. Also, in another ContentPlaceholder there is an asp button (outside of the UpdatePanel).
I want to refresh/reload the AJAX UpdatePanel with this asp button.
Thanks for suggestions.
Child Page Code :-
protected void Page_Load(object sender, EventArgs e)
{
ScriptManager ScriptManager1 = (ScriptManager)Master.FindControl("ScriptManager1");
ContentPlaceHolder cph = (ContentPlaceHolder)Master.FindControl("cp_Button");
Button btnRefresh = (Button)cph.FindControl("btnRefresh");
ScriptManager1.RegisterAsyncPostBackControl(btnRefresh);
}
protected void btnRefresh_Click(object sender, EventArgs e)
{
UpdatePanel1.Update();
}
<%# Page Title="" Language="C#" MasterPageFile="~/InnerMaster.master" AutoEventWireup="true" CodeFile="A.aspx.cs" Inherits="A" Async="true" %>
<asp:Content ID="Content3" ContentPlaceHolderID="MainContent" Runat="Server">
<asp:UpdatePanel ID="UpdatePanel1" UpdateMode="Conditional" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="id" DataSourceID="SqlDataSource1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Image ID="img12" runat="server" Width="650px" Height="600" ToolTip="A" ImageUrl='<%# Page.ResolveUrl(string.Format("~/Cli/{0}", Eval("image"))) %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
<asp:Content ID="Content4" ContentPlaceHolderID="cp_Button" Runat="Server">
<asp:Button ID ="btnRefresh" runat="server" onclick="btnRefresh_Click" Height="34" Width="110" Text="More Images" />
</asp:Content>
Hi updated code :- Now on click event whole pages is refreshed.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
namespace EProxy
{
public class EventProxy : Control, IPostBackEventHandler
{
public EventProxy()
{ }
public void RaisePostBackEvent(string eventArgument)
{ }
public event EventHandler<EventArgs> EventProxied;
protected virtual void OnEventProxy(EventArgs e)
{
if (this.EventProxied != null)
{
this.EventProxied(this, e);
}
}
public void ProxyEvent(EventArgs e)
{
OnEventProxy(e);
}
}
}
On Master Page Code (btn click):-
protected void btnRefresh_Click(object sender, EventArgs e)
{
ContentPlaceHolder cph = (ContentPlaceHolder)this.FindControl("MainContent");
EventProxy eventProxy = (EventProxy)cph.FindControl("ProxyControl") as EventProxy;
eventProxy.ProxyEvent(e);
}
Web Config :-
<pages maintainScrollPositionOnPostBack="true" enableViewStateMac="true">
<controls>
<add tagPrefix="it" namespace="EProxy" assembly="App_Code"/>
</controls>
</pages>
The reason that it doesn't work is because it's not possible to use a master page control directly as an AsyncPostBackTrigger for a child page control. However, there is a workaround that works by means of a proxy.
First, you need to create the following class (Put it in a seperate .cs file with the same name as the class):
public class EventProxy : Control, IPostBackEventHandler
{
public EventProxy()
{ }
public void RaisePostBackEvent(string eventArgument)
{ }
public event EventHandler<EventArgs> EventProxied;
protected virtual void OnEventProxy(EventArgs e)
{
if (this.EventProxied != null)
{
this.EventProxied(this, e);
}
}
public void ProxyEvent(EventArgs e)
{
OnEventProxy(e);
}
}
This class is a control that will be used to proxy the click event from the master page to the child page in order to refresh the UpdatePanel.
After you created the control, add the following after your UpdatePanel:
<it:EventProxy runat="server" ID="ProxyControl" />
Next, you need to indicate to your website / web application what 'it:EventProxy' is. To do that you need indicate that it is a control by adding it to the <controls> tag in your web.config file:
<pages maintainScrollPositionOnPostBack="true" theme="Default" enableViewStateMac="true">
<controls>
<add tagPrefix="it" namespace="The namespace that you saved the EventProxy class in" assembly="Your Assembly name"/>
</controls>
</pages>
In the above exmaple, set the value of the namespace attribute to the namespace of the EventProxy class, and set the value of the assembly attribute to your solution's name.
After you have done that, add the EventProxy control's EventProxied event as an AsyncPostBackTrigger to your UpdatePanel. Your markup should look something like the following:
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ProxyControl" EventName="EventProxied" />
</Triggers>
</asp:UpdatePanel>
<it:EventProxy runat="server" ID="ProxyControl" />
Then, call the following inside of your master page's button (That will be used to refresh the child page UpdatePanel) click event:
protected void btnRefresh_Click(object sender, EventArgs e)
{
EventProxy eventProxy = MasterPageContentPlaceHolder.FindControl("ProxyControl") as EventProxy;
eventProxy.ProxyEvent(e);
}
That's it!
Now what will happen is when you click the button in the master page, it will proxy the event of that click to the child page's EventProxy Control, that will in turn cause the UpdatePanel to refresh since the EventProxy control is one of its AsyncPostBackTriggers.
Place your button in it's own updatePanel or in the same updatePanel that you want to update with that button. Once yo do that, the updatePanel will update without codebehind, the button click will call an async postback for all controls inside all update panels.

Passing value from a user control to the main page aspx

I've a problem to pass a value from my user control to the aspx page. In the user control there is 2 textbox with a button to searh a customer and a gridview to show the results. When the select button is clicked I want to pass the value to the page.aspx. There is a button that when clicked, a modalpopupextender appears. Thi is the code:
<%# Control Language="C#" AutoEventWireup="true" CodeFile="searchCommittente.ascx.cs" Inherits="Assistenze_ControlliCustom_searchCommittente" %>
<%# Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>
<asp:TextBox runat="server" ID="lblNomeCommittente"/>
<asp:Button runat="server" ID="btnShow" Text="Cerca Committente" />
<asp:ModalPopupExtender runat="server" Y="155" ID="mpeCercaCommittente" TargetControlID="btnShow" OkControlID="btnSearch"
PopupControlID="pnlPopupContainer" CancelControlID="spnClose" BehaviorID="mpeCercaCommittente"/>
<asp:Panel runat="server" ID="pnlPopupContainer" CssClass="pnlPopupContainer">
<span id="spnClose"></span>
<asp:UpdatePanel runat="server" UpdateMode="Conditional">
<ContentTemplate>
<h2>Find Customer</h2>
<%=DateTime.Now%>
<asp:Panel runat="server" >
Referente :
<asp:TextBox ID="txtNomeReferente" runat="server" AutoPostBack="true"></asp:TextBox>
Committente :
<asp:TextBox ID="txtNomeCommittente" runat="server" AutoPostBack="true"></asp:TextBox>
<asp:Button ID="btnSearch" runat="server" Text="Search" onclick="btnSearch_Click"
CausesValidation="false" UseSubmitBehavior="false" />
</asp:Panel>
<p />
<asp:GridView ID="gvCommittenti" runat="server" AutoGenerateColumns="False"
AllowPaging="true" EnableViewState="False"
DataKeyNames="CustomerID"
DataSourceID="EntityDataSourceCommittenti"
OnSelectedIndexChanged="gvCommittenti_SelectedIndexChanged">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="CustomerID" HeaderText="Customer ID" SortExpression="CustomerID"/>
<asp:BoundField DataField="CompanyName" HeaderText="Company Name" SortExpression="CompanyName" />
<asp:BoundField DataField="ContactName" HeaderText="Contact Name" SortExpression="ContactName" />
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
</Columns>
</asp:GridView>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnSearch" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</asp:Panel>
<asp:EntityDataSource ID="EntityDataSourceCommittenti" runat="server" OrderBy=""
ConnectionString="name=NorthwindEntitiesCommittenti"
DefaultContainerName="NorthwindEntitiesCommittenti" EntityTypeFilter=""
EntitySetName="Customers" EnableFlattening="false"
Select="it.[CustomerID], it.[CompanyName], it.[ContactName], it.[Phone]" Where="it.[CompanyName] like #CompanyName"
AutoGenerateOrderByClause="True">
<WhereParameters>
<asp:FormParameter FormField="txtNomeCommittente" Name="CompanyName" DefaultValue="%" Type="String" />
</WhereParameters>
<OrderByParameters>
<asp:Parameter DefaultValue="it.[CustomerID]" Name="prmCustomerID"
Type="String" />
</OrderByParameters>
</asp:EntityDataSource>
I've tried with this event, but nothing happens:
protected void gvCommittenti_SelectedIndexChanged(object sender, GridViewSelectEventArgse)
{
((TextBox)Page.FindControl("ctl00$Body$txtTitolo")).Text = (string)gvCustomers.DataKeys[e.NewSelectedIndex][0];
mpeCercaCommittente.Hide();
}
Where txtTitolo is a textbox on the main aspx page.
Someone can help me that are 3 days I'm blocked on this.
Thanks in advance.
-----EDIT----
Thanks Brian,
I've made some changes to your post, but now it's finally working.
As you said I put the ThextoBox in un updatepanel:
Than I created inside the user Control the Delgate (I d'ont know but if I done as you wrote me, Visual studio 2010 went frozen):
public partial class Assistenze_ControlliCustom_searchCommittente : System.Web.UI.UserControl
{
public delegate void CommittenteSelectedHendler(string text);
public event CommittenteSelectedHendler custom;
.........................
Now when I click on the select button of the gridview, this function starts:
protected void gvCommittenti_SelectedIndexChanged(object sender, GridViewSelectEventArgs e)
{
if (custom != null)
{
string eventText = (string)gvCommittenti.DataKeys[e.NewSelectedIndex][0];
custom(eventText);
}
mpeCercaCommittente.Hide();
}
In this way the main page update the textbox using the registered event
that fires the procedure setTextBox:
public partial class Assistenze_AssistenzeIngresso : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ucCommittenteSearch.custom += new Assistenze_ControlliCustom_searchCommittente.CommittenteSelectedHendler(setTextBox);
chkFattura.Attributes.Add("onclick", "return cmode_check(this)");
Master.IdBody = "assistenze";
}
private void setTextBox(string text)
{
//set the text
txtCommittenteViewName.Text = text;
//update the page to reflect the change:
UpdatePanel1.Update();
}
.....................................................
Mission completed!
First thing to remember is that you are updating the page using a partial post, so the server-side display of the textbox is not updated on the main page, which could be part of your problem. Assuming that is not the only problem, the best way I've done this in the past is to use delegated events that the control can raise and the page subscribes to on the control.
To start, on your main page, make sure that you have the textbox you want updated inside of an update panel that is also marked with conditional update:
<asp:UpdatePanel ID="upd1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:TextBox ID="txtTitolo" runat="server"></asp:TextBox>
</ContentTemplate>
</asp:UpdatePanel>
in the code-behind on the main page (at namespace level, NOT at page level), add the delegate for the event:
namespace WebUserControlTalksToPage
{
//create the delegate to handle user-control updating page controls
public delegate void setPageText(string text);
public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// we'll add here in a second.
}
}
}
Next, go into the user control that you want to talk to the page (in your case the one with the gridview) and add the event to be raised:
public partial class SomeUserControl : System.Web.UI.UserControl
{
//create a public event on the delegate type defined in the namespace:
public event setPageText reporter;
public void Page_Load(object sender, EventArgs e)
{
//....
}
}
Next, add the reporter event to the event you want to raise it (in your case, the gvCommittenti_SelectedIndexChanged event:
protected void gvCommittenti_SelectedIndexChanged(object sender, GridViewSelectEventArgse)
{
//NOTE: you can add this in any event where you want
//to raise the event to the subscribers.
if (reporter != null)
{
//note: I separated this because I'm not testing your string. You will need
// to make sure the string you are sending is correct:
string eventText = (string)gvCustomers.DataKeys[e.NewSelectedIndex][0];
//this will raise the event to all subscribers:
reporter(eventText);
}
}
Next, you need to add the handler back on the page to respond (subscribe) to the event. In the main page_load, add the event:
protected void Page_Load(object sender, EventArgs e)
{
//'reporter' is the name of the event on the control
//setPageText is the name of the delegate event
//setTextBox is the event we will write to handle the raised event from the user control
//SomeUserControl1 is a variable name, replace with your UC name as defined in your page
this.SomeUserControl1.reporter += new setPageText(setTextBox);
}
Finally, you need to handle the event that is raised by the user control in the main page. Since the user control is doing a partial-page postback, you'll want to make sure to update the panel that contains the text as mentioned at the start of my response:
private void setTextBox(string text)
{
//set the text
this.txtTitolo.Text = text;
//update the page to reflect the change:
upd1.Update();
}
This should solve your problems. Let me know if anything about the response is unclear or confusing.

Categories