Get click event from linkbutton in compositecontrol in Web Forms

43 Views Asked by At

I have created a composite control which houses a number of tiles (which are also custom controls). In my web page I want to catch the click-event of a tile, but I can't figure out how.

This is the TileButton: (the components can be designed dynamically, but I left this part out to keep it simple)

public class TileButton : LinkButton
{
   public string Title { get; set; }
   public string ImageUrl { get; set; }

   private System.Web.UI.WebControls.Label title = 
       new System.Web.UI.WebControls.Label();
   private Image image = new Image();


   protected override void CreateChildControls()
   {
      base.CreateChildControls();
      title.Text = Title;
      image.ImageUrl = ImageUrl;
      Controls.Add(title);
      Controls.Add(image);
   }

   protected override void RenderContents(HtmlTextWriter writer)
   {
       RenderTitle(writer);
       RenderImage(writer);
   }

   private void RenderImage(HtmlTextWriter writer) 
   {
       writer.AddAttribute(HtmlTextWriterAttribute.Class, 
           "some css classes");
       writer.RenderBeginTag(HtmlTextWriterTag.Div);
       image.RenderControl(writer);
       writer.RenderEndTag();
   }

   private void RenderTitle(HtmlTextWriter writer)
   {
       writer.AddAttribute(HtmlTextWriterAttribute.Class, 
           "other css classes");
       writer.RenderBeginTag(HtmlTextWriterTag.Div);
       writer.AddAttribute(HtmlTextWriterAttribute.Class, 
           "title css classes");
       writer.RenderBeginTag(HtmlTextWriterTag.H6);
       title.RenderControl(writer);
       writer.RenderEndTag();
       writer.RenderEndTag();
   }
}

This is the composite control:

public class TilesControl : CompositeDataBoundControl
{
   public List<TileButton> TileButtons { get; set; } = 
       new List<TileButton>();

   protected override int CreateChildControls(IEnumerable datasource, bool databinding)
   {
      base.CreateChildControls();
      int count = 0;
      foreach (var item in datasource)
      {
          var tileButton = item as TileButton;
          tileButton.ID = "tile" + count;
          Controls.Add(tileButton);
          TileButtons.Add(tileButton);
          count++;
      }
      return count;
   }

   protected override void Render(HtmlTextWriter writer)
   {
      AddAttributesToRender(writer);

      writer.AddAttribute(HtmlTextWriterAttribute.Class, "some css classes");
      writer.RenderBeginTag(HtmlTextWriterTag.Div);

      foreach (var tile in TileButtons)
      {
         tile.CssClass = "button css classes";
         tile.RenderControl(writer);
      }

      writer.RenderEndTag();
   }
}

And in the page it's included like this:

<Something:TilesControl runat="server" ID="tiles1" DataSourceID="source1"></Something:TilesControl>

It all renders perfectly, the datasource is bound, but now I want the code behind to do something when a tileButton is clicked.

Extra: I would like the TileButton to have a property that defines WHAT to do when the button is clicked (some type of delegate?). Any pointers on that?

Thanks a lot.

1

There are 1 best solutions below

0
On

It looks like you are binding a List<TileButton> as the DataSource of TilesControl. So you can bind a Click event to one of those buttons in the List before you bind them as the DataSource.

protected void Page_Load(object sender, EventArgs e)
{
    //create a new tilescontrol instance
    TilesControl tc = new TilesControl();

    //create a list of tilebuttons
    List<TileButton> buttons = new List<TileButton>();

    //add some buttons for testing
    for (int i = 0; i < 10; i++)
    {
        TileButton b = new TileButton();

        b.ID = "TileButton" + i;
        b.Title = "TileButton " + i;

        //add the click event of a button here
        b.Click += TileButton_Click;

        //add the button to the list
        buttons.Add(b);
    }

    //bind the list of buttons to the tilescontrol
    tc.DataSource = buttons;
    tc.DataBind();

    //add the tilescontrol to the page
    PlaceHolder1.Controls.Add(tc);
}

private void TileButton_Click(object sender, EventArgs e)
{
    //display results
    Label1.Text = ((TileButton)sender).Title + " Clicked!";
}