views:

246

answers:

1

I want to change the value of the text in a ButtonField depending on other factors. Some code:

 public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
 {
  base.InitializeCell(cell, cellType, rowState, rowIndex);

  bool isDataRowAndIsHighlightFieldSpecified = cellType == DataControlCellType.DataCell && !string.IsNullOrEmpty(UnnpiFlagField);
  if (isDataRowAndIsHighlightFieldSpecified)
  {
   cell.DataBinding += new EventHandler(cell_DataBinding);
  }
 }

 private void cell_DataBinding(object sender, EventArgs e)
 {
  TableCell cell = (TableCell)sender;
  object dataItem = DataBinder.GetDataItem(cell.NamingContainer);

  IButtonControl button = cell.Controls[0] as IButtonControl;
  button.Text = DataBinder.GetPropertyValue(dataItem, DataTextField).ToString();
  bool highlightTheText = DataBinder.GetPropertyValue(dataItem, IsFlagField).ToString().ToUpper() == "Y";
  if (highlightTheText)
  {
   cell.CssClass = string.Concat(ItemStyle.CssClass, " thisChangesFine");
   button.Text = "CHANGE ME";
  }
 }

This code works great for BoundField, in which the cell's Text is changed and highlighted but even though the button control does indeed have a button with the correct CommandName set through the aspx page, the Text value initially contains nothing and seems to be set somewhere else. When I set it here to another value it seems to be resetting to the original value someplace else. Looking into Reflector I don't see where this could be happening. Reflector shows:

protected override DataControlField CreateField()
public override bool Initialize(bool sortingEnabled, Control control)
private void OnDataBindField(object sender, EventArgs e) [Can't get that one :(]
protected override void CopyProperties(DataControlField newField)
protected virtual string FormatDataTextValue(object dataTextValue)
public override void ValidateSupportsCallback()

I've checked each one and I don't see the value getting set. That does seem to be happening in the OnDataBindField(object, EventArgs) here:

if ((this.textFieldDesc == null) && (component != null))
    {
        ...
        this.textFieldDesc = TypeDescriptor.GetProperties(component).Find(dataTextField, true);
        ...
    } 
    if ((this.textFieldDesc != null) && (component != null))
    {
        object dataTextValue = this.textFieldDesc.GetValue(component);
        str = this.FormatDataTextValue(dataTextValue);
    }
  ...
  ((IButtonControl) control).Text = str;

Which I would think would be happening BEFORE I'm trying to change the value, but as I've said before it seems that button.Text is string.Empty in the cell_DataBinding method.

Anyone have any ideas?

A: 

I go through in the databound event and create a list of strings to emit when the PreRender is called:

            public override void InitializeCell(DataControlFieldCell cell, DataControlCellType cellType, DataControlRowState rowState, int rowIndex)
 {
  base.InitializeCell(cell, cellType, rowState, rowIndex);

  bool isDataRowAndIsHighlightFieldSpecified = cellType == DataControlCellType.DataCell && !string.IsNullOrEmpty(SpecialField);
  if (isDataRowAndIsHighlightFieldSpecified)
  {
   cell.DataBinding += new EventHandler(cell_DataBinding);
   cell.PreRender += new EventHandler(cell_PreRender);
  }
 }

and

 IList<string> buttonsText = new List<string>();
 private void cell_DataBinding(object sender, EventArgs e)
 {
  TableCell cell = (TableCell)sender;
  object dataItem = DataBinder.GetDataItem(cell.NamingContainer);
  bool specialData = DataBinder.GetPropertyValue(dataItem, SpecialField);
  if (specialData)
  {
   cell.CssClass = string.Concat(ItemStyle.CssClass, " special");
   buttonsText.Add("Replace text");
        }
  else
  {
   buttonsText.Add(DataBinder.GetPropertyValue(dataItem, DataTextField).ToString());
  }
 }

and finally in the pre render:

 void cell_PreRender(object sender, EventArgs e)
 {
  TableCell cell = (TableCell)sender;
  IButtonControl button = cell.Controls[0] as IButtonControl;
  int index = ((GridViewRow)cell.NamingContainer).RowIndex;
  button.Text = buttonsText[index];
 }

The only downfall of this approach is that you have to call databind. I am though so it wasn't an issue for me and worked peachy.

rball