Saturday, April 12, 2014

adding events to event handlers at DevExpress ASPxGridView controls to achieve "dress up" effects

Do the event binding on the C# side as seen below. (In this example SolarSystem is a ASPxGridView.)

private void SetSolarSystem()
{
   SolarSystem.HtmlDataCellPrepared += SolarSystem_HtmlDataCellPrepared;
   SolarSystem.HtmlEditFormCreated += SolarSystem_HtmlEditFormCreated;
   SolarSystem.RowDeleting += SolarSystem_RowDeleting;
   SolarSystem.RowInserting += SolarSystem_RowInserting;
   SolarSystem.RowUpdating += SolarSystem_RowUpdating;
   SolarSystem.RowValidating += SolarSystem_RowValidating;
   SolarSystem.SettingsEditing.Mode = GridViewEditingMode.PopupEditForm;
   SolarSystem.DataSource = Session["planets"];
   SolarSystem.DataBind();
}

 
 

Um... well, I guess now we need events to go with SolarSystem_HtmlDataCellPrepared, SolarSystem_HtmlEditFormCreated, SolarSystem_RowDeleting, SolarSystem_RowInserting, SolarSystem_RowUpdating, and SolarSystem_RowValidating. I have written them here in the name of doctoring up what I originally had here and I will discuss half of these in detail. First off I am using a nullable DateTime for a planet's discovery date. If the discovery date is null I wish to denote that the planet was discovered before recorded human history. I do that like so:

private void SolarSystem_HtmlDataCellPrepared(object sender,
      ASPxGridViewTableDataCellEventArgs e)
{
   if (e.DataColumn.FieldName == "DiscoveryDate" && e.CellValue == null)
   {
      e.Cell.Text = "prehistory";
      e.Cell.ForeColor = Color.Firebrick;
      e.Cell.Font.Size = 8;
   }
}

 
 

ClosestAstronomicalUnitDistanceFromSun is a mouthful and sure does take up a lot of real estate in the form for adding and editing entries. I fix that below and I also put the name of the planet being edited into the title of the token tab on the form.

private void SolarSystem_HtmlEditFormCreated(object sender,
      ASPxGridViewEditFormEventArgs e)
{
   ASPxPageControl outerWrapper =
      (ASPxPageControl)SolarSystem.FindEditFormTemplateControl("PageControl");
   GridViewEditFormTable innerWrapper =
      (GridViewEditFormTable)outerWrapper.ActiveTabPage.FindControl("DXEFT");
   LiteralControl literal =
      (LiteralControl)innerWrapper.Rows[0].Cells[2].Controls[0].Controls[0];
   literal.Text = "AU Distance";
   ASPxTextBox firstTextBox =
      (ASPxTextBox)outerWrapper.ActiveTabPage.FindControl("DXEditor1");
   outerWrapper.ActiveTabPage.Text = firstTextBox.Text;
}

 
 

The RowValidating event handler provides a place to do validations. I prevent one from naming a planet a name that has already been specified.

private void SolarSystem_RowValidating(object sender, ASPxDataValidationEventArgs e)
{
   List<Planet> revamp = RevampPlanets(e.OldValues, e.NewValues);
   if (IsNamingCollision(revamp)) e.RowError = "You may not have a duplicate name.";
}

 
 

The validation safeguard caused some really strange effects. Even if when a validation failed the row in the grid would get updated and even if I was also making the same validation check at RowInserting or RowUpdating. I got around the problem by making my RowInserting and RowUpdating implementations explictly write to a dummy collection and then overwriting my "real" collection with the staging grounds (if applicable). I am guessing that without this step there is some DevExpress magic to do with pointers for reference types that goes on beneath the hood which I do not yet understand which are getting in the way of my implementation.

No comments:

Post a Comment