I am developing a MS Word 2010 AddIn, in which I have a combobox which updates a class property when it is changed:
private void comboboxFloweringStart_SelectedIndexChanged(object sender, EventArgs e)
{
Globals.ThisAddIn.currentTaxon.FloweringStart = (short)this.comboboxFloweringStart.SelectedIndex;
}
This class is serialized on shutdown (ThisAddIn_Shutdown event handler). The combobox is located on Microsoft.Office.Tools.CustomTaskPane taxonMarkupPanel based on the user control TaxonPanel myTaxonPanel which I designed.
The problem is that at some point before the shutdown event fires, the SelectedIndexChanged event on the combobox fires and resets the value to 0, and this is the value that is serialized. I know that I could use SelectionChangeCommitted instead of SelectedIndexChanged, but I do at times set the index in code, and the event should fire in these cases too.
The CustomTaskPane does not have a close event that I could use to unsubscribe the event handler and I don't know the order of events when a VSTO is closed. Is there some other event I could subscribe to, or some other way that I can unsubscribe the SelectedIndexChanged event handler when the custom task pane / user control is closed?
You should subscribe to the DocumentBeforeClose event of the Application, and/or Close event of the Document.
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
Word.Application app = this.Application;
Word.Document doc = app.ActiveDocument;
app.DocumentBeforeClose += new Word.ApplicationEvents4_DocumentBeforeCloseEventHandler(ThisAddIn_DocumentBeforeClose);
((Word.DocumentEvents2_Event)doc).Close += new Word.DocumentEvents2_CloseEventHandler(ActiveDocument_Close);
}
private void ThisAddIn_DocumentBeforeClose(Word.Document doc, ref bool cancel)
{
MessageBox.Show(string.Format ("Document {0} is closing.", doc.Name));
}
private void ActiveDocument_Close()
{
MessageBox.Show("Active document is closing.");
}
Related
I’ve made a handy “user control” for login to my website and it is placed in the site master.
The natural procedure is that the user logs in the web site and he should be announced with a welcome message containing its full name. The full-Name naturally should sits in a session variable created when the user logged on.
There is no doubt that we place the desired code in the “page_load” event and expect it to pass user’s full-name to the right circumstances (here its a label named lblFullName) in order to print/show the welcome message when login button clicked, But the full-name doesn’t passed until the user logs in the website again (for the 2nd times).
Why this problem happens?
Its some part of my code:
protected void Page_Load(object sender, EventArgs e)
{
if (Session["FullName"]==null)
{
//nothing 2 do.
}
else
{
lblFullName.Text = Session["FullName"].ToString();
}
}
You probably set the Session variable in the user control after the Page_Load event has been processed, so that it will not see the user name until the next postback.
In order to update the Label text as soon as the login is validated, you could:
Define an event in the user control
Register an event handler in the main page
Call the event handler as soon as the user has logged in
In the event handler, update the Label text
You could also eliminate the Session variable by passing the user full name in an EventArgs derived class. If you make the following class accessible in the user control and in the main form:
public class StringEventArgs : EventArgs
{
public string Value { get; set; }
public StringEventArgs(string value)
{
Value = value;
}
}
then you can define this event in the user control:
public event EventHandler<StringEventArgs> UserLoggedIn;
In the function where the login is confirmed, you call the event handlers:
private void UserLoginValidation()
{
// Login validation is done here
bool loginSuccessful = ...
if (loginSuccessful && UserLoggedIn != null)
{
UserLoggedIn(this, new StringEventArgs(fullName));
}
}
In the main page, you register the event handler, which updates the Label:
protected void Page_Load(object sender, EventArgs e)
{
loginUserControl1.UserLoggedIn += loginUserControl1_UserLoggedIn;
...
}
private void loginUserControl1_UserLoggedIn(object sender, StringEventArgs e)
{
lblFullName.Text = e.Value;
}
I have a RadGrid control which is created dynamically on page_init and added to a placeholder which is inside an updatePanel on the page.
I'd need to add a new Button to the CommandItem section of the RadGrid. The button has to support full postback.
RadGrid has an event called RadGrid_ItemCreated() and that's where I've added my new button and it appears on my RadGrid:
protected virtual void RdGridItemCreated(object sender, GridItemEventArgs e)
{
var itemType = e.Item.ItemType;
switch (itemType)
{
// other cases...
case GridItemType.CommandItem:
{
var gridCommandItem = e.Item as GridCommandItem;
if (gridCommandItem == null) return;
if (this.EnablePdfExport)
{
var pdfButton = CreateExportToPdfButton();
PageUtil.RegisterPostBackControl(pdfButton);
// this is the cell which contains the export buttons.
((Table)gridCommandItem.Cells[0].Controls[0]).Rows[0].Cells[1].Controls.Add(pdfButton);
}
break;
}
}
}
The button has a Click event and a method has been added to it as an event handler:
private Button CreateExportToPdfButton()
{
var result = new Button();
result.ID = "btnExportToPdf";
result.Click += ExportToPdfButtonClick;
result.CssClass = "rgExpPDF";
result.CommandName = "ExportToPdf";
result.Attributes.Add("title", "Export to Pdf");
return result;
}
To register the postback event for this control I've used the RegisterPostBackControl() method of the ScriptManager.
public static void RegisterPostBackControl(Control control)
{
var currentPage = (Page) HttpContext.Current.CurrentHandler;
var currentScriptManager = ScriptManager.GetCurrent(currentPage);
if (currentScriptManager != null)
{
currentScriptManager.RegisterPostBackControl(control);
}
}
When I click the button on the RadGrid, it posts back to the server but the problem is that its Click event is never raised:
private void ExportToPdfButtonClick(object sender, EventArgs e)
{
// process
}
I don't understand why; any thoughts/help?
If I don't set ID for the button, then the click event is raised but a new problem arises in that case. When a partial postback happens on the page by an external drop downlist to update the radgrid, then my custom export button sends postbacks asynchronously whereas it should post back fully.
Many thanks,
I fixed it by adding the new control in the following event:
this.RadGrid.MasterTableView.Init += MasterTableViewInit;
void MasterTableViewInit(object sender, EventArgs e)
{
if (!this.EnablePdfExport) return;
var commandItem = this.RadGrid.MasterTableView.GetItems(GridItemType.CommandItem).SingleOrDefault();
if (commandItem == null) return;
AddPdfButton(commandItem as GridCommandItem);
}
I am having the same problem. I have tracked it down to Telerik switching the Visible property of the child controls of the RadGrid to false during Render. This only affects partial-page postbacks because Render gets called before the PageRequestManager writes the JavaScript for the postback controls, and it skips controls which are not Visible. For a full postback (or the initial page load), the PageRequestManager writes the JavaScript for the postback controls before the RadGrid is Rendered, and thus the controls are still Visible.
I'm not sure why Telerik is doing this as it causes a lot of problems to muck with the Visible property during the Render stage.
I have C# Web Application that has an aspx page hosting a user control (Review.ascx). Inside that user control there are 5 more user controls, one of which has a public event (Review_Summary.ascx). The problem is no matter what i do I cannot get the event wired up in the parent ascx control (Review.ascx).
Here is what I have in the child control (Review_Summary.ascx)
public event EventHandler forwardStatusChanged;
#region methods
protected void btnForward_Click(object sender, EventArgs e)
{
if (btnForward.Text == "Return")
{
if (forwardStatusChanged != null)
{
forwardStatusChanged(sender, e);
}
removeForward();
}
}
In the parent control (Review.ascx) I have this
public void initReview(string EmployeeNumber)
{
RevSummary.forwardStatusChanged += new EventHandler(RevSummary_forwardStatusChanged);
<more code here>
}
protected void RevSummary_forwardStatusChanged(object sender, EventArgs e)
{
lblReadOnly.Visible = false;
}
RevSummary is the ID of the child control in the parent control. InitReveiw is a method that is called by the aspx page in its Page_Load event.
I get no errors on compile or at runtime. But when I click the button the forwardStatusChanged event is null. The "removeForward()" method that is called after that executes properly. So that fact that the event is always null leads me to believe that the wire up in the parent control is not working. However, I am sure it is executing becasue all of the code after that executes.
How can I figure out why this event is not wiring up?
Where is initReview being called from? Are you sure it's being called because the only reason this happens is that the event handler wasn't truly setup. I've never found a reason other than this, the several times I did this myself.
HTH.
I am migrating from ASP.NET 1.1 and I used to subscribe to page events using designer which adds subscriptions to InitializeComponent method on the page.
In the ASP.NET 2.0, how can I subscribe to Page events from the designer?
Not using designer this seems to work.
protected void Page_Init(object sender, EventArgs e) {
// The code, no safety here, just convention
}
// OR
protected override void OnInit(EventArgs e) {
base.OnInit(e);
// The code
}
What is the recommended way of subscribing to page events? Same question applies to the MasterPage.
Additionally what is the best way to subscribe to events on the UserControl? When I declare the Page_XXX on the UserControl the event gets called many times.
Pages support auto event-wire-up, meaning that ASP.NET looks for methods with particular names and automatically runs those methods when certain events are raised. If the AutoEventWireUp attribute of the Page directive is set to true (bydefault it is true - asp.net 2.0), page events are automatically bound to methods that use the naming convention of Page_Event, such as Page_Load, Page_PreInit, Page_Init etc.
void Page_PreInit(){
}
void Page_Init(){
}
EDIT:
#Dmitriy : So only the method name matters?
Yes
#Dmitriy : Also how do you subscribe to events from designer?
You can't subscribe page events through designer.
See this example: How to add event handler for page events if AutoEventWireUp is false?
public _Default() //Constructor
{
this.Load += new EventHandler(_Default_Load);
}
void _Default_Load(object sender, EventArgs e)
{
}
I need to perform a few checks (enable or disable a label elsewhere on the page) after the user Inserts or Cancels the DetailsView. I have to do this because the DropDownList.SelectedIndexChanged doesn't fire during this event (which is dumb in my opinion, since the index DOES change).
ModeChanging should fire, so can you do this?
protected void DetailsView1_ModeChanging(object sender, DetailsViewModeEventArgs e)
{
if (e.CancelingEdit)
{
//Checks
}
}