Changing the color of a custom control

1.1k views Asked by At

I am trying to set the background color of a custom button. I build that button from HTML by overriding the Render method. I then expose certain attributes through customer overridden attribute methods with Get and set capabilities. This allows my to change parts of my custom button after compiling.

I want to change the color of the buttons div or table (i dont care which). How can i do this?

The button has a table - how can i programmatically grab this table given i know its name ;buttonTable.FindControl not working, i get 'not set to an instance of an object' error.

    Panel buttonPnl = new Panel(); //Declare and Init here in case you need it for changing background color at code compile and not run time
    System.Web.UI.WebControls.Image logoImg;
    System.Web.UI.WebControls.Image errorImg;
    TextBox mainTextTb;
    Label subTextLbl;

    protected override void CreateChildControls()
    {
        Controls.Clear();

        //init controls
        //buttonPnl.Width = Unit.Pixel(200);
        //buttonPnl.Height = Unit.Pixel(150);
        buttonPnl.ID = "buttonPnl";

        logoImg = new System.Web.UI.WebControls.Image();
        logoImg.ID = "logoImg";
        logoImg.Width = Unit.Pixel(75);
        logoImg.Height = Unit.Pixel(75);

        errorImg = new System.Web.UI.WebControls.Image();
        errorImg.ID = "errorImg";
        errorImg.Width = Unit.Pixel(50);
        errorImg.Height = Unit.Pixel(50);

        mainTextTb = new TextBox();
        mainTextTb.ID = "mainTextTb";
        mainTextTb.Text = "changed";
        mainTextTb.Font.Size = 20;
        mainTextTb.Width = Unit.Pixel(180);


        subTextLbl = new Label();
        subTextLbl.ID = "subTextLbl";
        subTextLbl.Text = "sub text";
        subTextLbl.Font.Size = 12;

        //add controls to parent control
        this.Controls.Add(logoImg);
        this.Controls.Add(errorImg);
        this.Controls.Add(mainTextTb);
        this.Controls.Add(subTextLbl);
        this.Controls.Add(buttonPnl);
    }

    protected override void Render(HtmlTextWriter writer)
    {
        //render controls
        buttonPnl.RenderControl(writer);
        AddAttributesToRender(writer);
        writer.RenderBeginTag(HtmlTextWriterTag.Div); //table start tag
        writer.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "5");
        writer.AddAttribute(HtmlTextWriterAttribute.Width, "200");
        writer.AddAttribute(HtmlTextWriterAttribute.Id, "buttonTable");
        writer.RenderBeginTag(HtmlTextWriterTag.Table); //table start tag
        writer.RenderBeginTag(HtmlTextWriterTag.Tr); //row start tag
        writer.RenderBeginTag(HtmlTextWriterTag.Td); // cell start tag
        logoImg.RenderControl(writer); //add logo image
        writer.RenderEndTag(); //cell end tag
        writer.RenderBeginTag(HtmlTextWriterTag.Td); //cell start tag
        errorImg.RenderControl(writer); //add error image
        writer.RenderEndTag(); //cell end tag
        writer.RenderEndTag(); //row end tag
        writer.RenderBeginTag(HtmlTextWriterTag.Tr); //row start tag
        writer.AddAttribute(HtmlTextWriterAttribute.Width, "100%"); //make sure row width is 100% of parent
        writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); //make sure row spans 2 cells
        writer.RenderBeginTag(HtmlTextWriterTag.Td); //cell start tag
        mainTextTb.RenderControl(writer); //add main text box
        writer.RenderEndTag(); //cell end tag
        writer.RenderEndTag(); //row end tag
        writer.AddAttribute(HtmlTextWriterAttribute.Align, "right"); //make sure row width is 100% of parent
        writer.RenderBeginTag(HtmlTextWriterTag.Tr); //row start tag
        writer.AddAttribute(HtmlTextWriterAttribute.Width, "100%"); //make sure row width is 100% of parent
        writer.AddAttribute(HtmlTextWriterAttribute.Colspan, "2"); //make sure row spans 2 cells
        writer.RenderBeginTag(HtmlTextWriterTag.Td); //cell start tag
        subTextLbl.RenderControl(writer); //add sub label
        writer.RenderEndTag();//cell end tag
        writer.RenderEndTag(); //row end tag
        writer.RenderEndTag(); //table end tag
        writer.RenderEndTag(); //div end tag
    }

    [Category("Appearance")]
    [Description("Gets or sets the panel colour")]
    public Color TimbusButtonColour
    {                

        get
        {
            EnsureChildControls();
            Table buttonTbl = (Table)this.FindControl("buttonTable");
            //return buttonPnl.BackColor;
            return buttonTbl.BackColor;
        }

        set
        {
            if (value != null)
            {
                Table buttonTbl = (Table)this.FindControl("buttonTable");
                //buttonPnl.BackColor = Color.FromArgb(value.R, value.G, value.B);
                buttonTbl.BackColor = Color.FromArgb(value.R, value.G, value.B);
            }
        }
    }

resulting HTML from pages source code

</div><div id="Button1">
    <table cellpadding="5" width="200" id="buttonTable">
        <tr>
            <td><img id="Button1_logoImg" src="" style="height:75px;width:75px;" /></td><td><img id="Button1_errorImg" src="" style="height:50px;width:50px;" /></td>
        </tr><tr>
            <td width="100%" colspan="2"><input name="Button1$mainTextTb" type="text" value="changed" id="Button1_mainTextTb" style="font-size:20pt;width:180px;" /></td>
        </tr><tr align="right">
            <td width="100%" colspan="2"><span id="Button1_subTextLbl" style="font-size:12pt;">sub text</span></td>
        </tr>
    </table>
</div>
2

There are 2 answers

5
SmartDev On

You should use a function similar to this:

public static Control FindControlRecursive(Control ctl, string id) {
    if (!ctl.HasControls())
        return null;
    Control res = null;
    foreach(Control c in ctl.Controls) {
        if (c.ID == id) {
            res = c;
            break;
        } else {
            res = FindControlRecursive(c, id);
            if (res != null)
                break;
        }
    }
    return res;
}

in this way:

Table buttonTbl = (Table)FindControlRecursive(this.Page, "buttonTable");

And you will find your control for sure.

2
Fearghal On

Thx Igor and Patrick et al, great feedback put me back on the right path, ie creating controls and not going straight to dynamically writting html. seems obv but there you go.

    protected override void CreateChildControls()
    {
        Controls.Clear();

        //init controls
        buttonTbl = new Table();
        buttonPnl.ID = "buttonPnl";

        logoImg = new System.Web.UI.WebControls.Image();
        logoImg.ID = "logoImg";
        logoImg.Width = Unit.Percentage(100);//100% of cell width
        logoImg.Height = Unit.Percentage(100);//100% of cell width

        errorImg = new System.Web.UI.WebControls.Image();
        errorImg.ID = "errorImg";
        errorImg.Width = Unit.Percentage(50);//50% of cell width
        errorImg.Height = Unit.Percentage(50);//50% of cell height

        mainTextTb = new TextBox();
        mainTextTb.ID = "mainTextTb";
        mainTextTb.Text = "changed";
        mainTextTb.Font.Size = 20;
        mainTextTb.Width = Unit.Percentage(100);

        subTextLbl = new Label();
        subTextLbl.ID = "subTextLbl";
        subTextLbl.Text = "sub text";
        subTextLbl.Font.Size = 12;

        //format table
        buttonTbl.Width = 200;
        buttonTbl.Height = 150;
        buttonTbl.CellPadding = (int)Unit.Percentage(5).Value;
        //add the 3 rows
        buttonTbl.Rows.Add(imgRow);
        buttonTbl.Rows.Add(mainTextRow);
        buttonTbl.Rows.Add(subTextRow);
        //add the cells
        imgRow.Cells.Add(logoImgCell);
        imgRow.Cells.Add(errorImgCell);
        mainTextRow.Cells.Add(mainTextCell);
        subTextRow.Cells.Add(subTextCell);
        //add controls to their cells
        logoImgCell.Controls.Add(logoImg);
        errorImgCell.Controls.Add(errorImg);
        mainTextCell.Controls.Add(mainTextTb);
        subTextCell.Controls.Add(subTextLbl);
        //position cells
        logoImgCell.HorizontalAlign = HorizontalAlign.Right;
        logoImgCell.VerticalAlign = VerticalAlign.Top;
        errorImgCell.HorizontalAlign = HorizontalAlign.Right;
        errorImgCell.VerticalAlign = VerticalAlign.Top;
        mainTextCell.ColumnSpan = 2;
        subTextCell.ColumnSpan = 2;
        subTextCell.HorizontalAlign = HorizontalAlign.Right;

        this.Controls.Add(buttonTbl);
    }

    protected override void Render(HtmlTextWriter writer)
    {
        //render controls
        buttonTbl.RenderControl(writer);
    }

    [Category("Appearance")]
    [Description("Gets or sets the panel colour")]
    public Color TimbusButtonColour
    {                
        get
        {
            EnsureChildControls();
            return buttonTbl.BackColor;
        }

        set
        {
            if (value != null)
            {
                buttonTbl.BackColor = Color.FromArgb(value.R, value.G, value.B);
            }
        }
    }