Textbox rendered as label - c#

I have created a custom web server control that will have a bool property 'RenderAsLabel' so that I can convert textboxes to labels, for Read-only forms. I was wondering if there is any reason why this code should not be safe, or work as intended. Upon initial testing it seems fine, but I just want to make sure I'm not doing something that will end up causing issues.
namespace OrmControlLibrary
{
[DefaultProperty("Text")]
[ToolboxData("<{0}:OrmTextBox ID='' runat=server ></{0}:OrmTextBox>")]
public class OrmTextBox : TextBox
{
private Label lbl;
public virtual bool RenderAsLabel
{
get
{
if (ViewState["OrmTextBox"] == null)
{
return false;
}
else
{
return (bool)ViewState["OrmTextBox"];
}
}
set
{
ViewState["OrmTextBox"] = value;
}
}
protected override void Render(HtmlTextWriter w)
{
if (RenderAsLabel)
{
SetLabelProperties();
lbl.RenderControl(w);
}
else
{
base.Render(w);
}
}
private void SetLabelProperties()
{
lbl = new Label();
lbl.ID = this.ID;
lbl.CssClass = this.CssClass;
lbl.Text = this.Text;
}
}
}

Related

Reseting label back to design-time .Text value

I have a bunch of labels that I set their value in the designer and later during runtime update them, but after using them, I want to set them back to their default value. My intent with this is to reduce the amount of large code to help make it easier to read.
random example like, setting in the designer of lbl_fruit Text = no fruits available currently then
*code*
lbl_fruits.Text = "banana";
*code*
lbl_fruits.ResetText(); // I want something like this
lbl_fruits.Text = "no fruits available currently"; // Instead of this
The .ResetText(); doesn't work for this as the label text gets cleaned instead of returning to "no fruits available currently"
My current solution is making a custom label control.
public class ExLabel : Label
{
private string defaultValue = "";
public string DefaultValue
{
get { return defaultValue; }
set { defaultValue = value; this.Invalidate(); }
}
protected override void OnControlAdded(ControlEventArgs e)
{
defaultValue = this.Text;
MessageBox.Show("This code is being run");
base.OnControlAdded(e);
}
public void ResetValue()
{
this.Text = defaultValue;
}
}
This code currently solves my problem if I use the custom propriety I made, but for me the ideal solution would be to have the design-time text value as the default value and not an extra propriety I made. OnControlAdded() does not get executed, OnPaint() runs again when lbl_fruits.Text = "banana"; happens.
So the question is: Which event I can override so the code gets executed as soon as the label is loaded but doesn't run twice. And also, is there a simpler way of approaching this?
In the end the solution I used was this:
public class ExLabel : Label
{
private string defaultValue = "";
public string DefaultValue
{
get { return defaultValue; }
set { defaultValue = value; this.Invalidate(); }
}
protected override void OnPaint(PaintEventArgs e)
{
if(defaultValue == "" && !this.Text.Contains("exLabel"))
{
defaultValue = this.Text;
}
base.OnPaint(e);
}
public void ResetValue()
{
this.Text = defaultValue;
}
}
public class ExLabel : Label
{
private string defaultValue = "";
public string DefaultValue
{
get { return defaultValue; }
set { defaultValue = value; this.Invalidate(); }
}
protected override void OnControlAdded(ControlEventArgs e)
{
defaultValue = this.Text;
MessageBox.Show("This code is being run");
base.OnControlAdded(e);
}
public void ResetValue()
{
this.Text = defaultValue;
}
}

Can't Set Custom TextBox text via the properties window in visual studio

I am trying to set the text in my custom textbox with a variable that I can preset in the visual studio properties window, but the variable keeps ending up empty
namespace CustomControlTest
{
public partial class MyTextField : TextBox
{
public MyTextField()
{
InitializeComponent();
this.Text = "Potato";
this.Text = GhostText;
if(GhostText == null)
{
this.Text = "Orange";
}
}
public string GhostText { get; set; }
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
}
}
The textbox text gets set to "Orange" which i don't understand because I have set it to "Something" in the visual studio properties.
I want to be able to set the value of GhostText from her
What am I doing wrong here ?
I think this may help you to solve your problem:
namespace CustomControlTest
{
public partial class MyTextField : TextBox
{
public MyTextField()
{
InitializeComponent();
}
private string _ghostText;
public string GhostText
{
get
{
return _ghostText;
}
set
{
this.Text = value;
_ghostText = value;
}
}
}
}
and in some other class:
var ctr = new MyTextField ();
ctr.GhostText = "Something";

Textchanges only visible after postback

I have a method that changes the text of the controls on my site.
These changes should be visible right when the user loads the page.
But the changes are first visible after the next postback.
I tried to call it in Page_PreInit, Page_Init, Page_PreLoad and and all the other methods described here.
But none of them worked.
Some code:
The class with the methods: (partly)
namespace MyNamespace {
public class ControlTextCorrection {
Page _page;
public ControlTextCorrection(Page page) {
_page = page;
}
public void Correct() {
HtmlEncodeControls(_page);
}
private void HtmlEncodeControls(Page page) {
Control control = (Control)page;
HtmlEncodeControls(control);
}
private void HtmlEncodeControls(Control parentControl) {
if (!parentControl.HasControls()) {
return;
}
foreach (Control control in parentControl.Controls) {
if (control.HasControls()) {
HtmlEncodeControls(control);
}
if (control is Label) {
Label label = (Label)control;
label.Text = HtmlTextCorrection(label.Text);
}
else if (control is CheckBox) {
CheckBox checkBox = (CheckBox)control;
checkBox.Text = HtmlTextCorrection(checkBox.Text);
}
//Correction for more controls...
}
}
protected string HtmlTextCorrection(string text) {
bool encode = true;
while (encode) {
string newText = _page.Server.HtmlDecode(text);
if (newText == text) {
encode = false;
}
text = newText;
}
text = _page.Server.HtmlEncode(text);
return text;
}
}
}
Example for calling the method:
protected void Page_PreLoad(object sender, EventArgs e) {
ControlTextCorrection correction = new ControlTextCorrection(this.Page);
correction.Correct();
}
So, where (when) should i call it so that the changes are visible at the first sight of the site?

Programically adding child controls to a asp.net composite control

Not found anything that directly answers my problem, so hopefully someone can shed some light on it.
I have two Composite Controls, lets call them BudgetTable and BudgetTableItem, where BudgetTable contains a list of BudgetTableItem.
So far everything works so long as I add new RowItems in the HTML View - when I add one programmatically it appears, but doesn't survive postback.
I can only assume I'm doing something boneheaded with ViewState, and would appreciate any pointers!
Thanks in advance.
The HTML:
<hea:BudgetTable runat="server" ID="btTest" MaximumFundingAvailable="7000" CssClass="bob">
<Items>
<hea:BudgetTableItem runat="server" Description="Test1" />
<hea:BudgetTableItem runat="server" Description="Test2" />
<hea:BudgetTableItem runat="server" Description="Test3" />
</Items>
</hea:BudgetTable>
The code behind:
[PersistenceMode(PersistenceMode.InnerProperty)]
[ParseChildren(true)]
public class BudgetTableItem : CompositeControl {
private TextBox _description = new TextBox();
private TextBox _cost = new TextBox();
private CheckBox _heaFunded = new CheckBox();
/*public delegate void AddRow();
public delegate void RemoveRow(BudgetTableItem item);
public event AddRow AddNewRow;
public event RemoveRow RemoveNewRow;*/
public string ItemName {
get {
var viewstate = ViewState["ItemName"];
return (viewstate is string) ? (string)viewstate : "default";
}
set {
ViewState["ItemName"] = value;
}
}
public bool ShowRemoveRow {
get {
var viewstate = ViewState["ShowRemoveRow"];
return (viewstate != null && viewstate is bool) ? (bool)viewstate : false;
}
set {
ViewState["ShowRemoveRow"] = value;
}
}
public bool ShowAddRow {
get {
var viewstate = ViewState["ShowAddRow"];
return (viewstate != null && viewstate is bool) ? (bool)viewstate : false;
}
set {
ViewState["ShowAddRow"] = value;
}
}
public string Description {
get {
return _description.Text;
}
set {
_description.Text = value;
}
}
public decimal Cost {
get {
decimal cost =0;
decimal.TryParse(_cost.Text, out cost);
return cost;
}
set {
_cost.Text = value.ToString();
}
}
public bool HeaFunded {
get {
return _heaFunded.Checked;
}
set {
_heaFunded.Checked = value;
}
}
protected override void CreateChildControls() {
Controls.Clear();
HtmlTableCell tableCell1 = new HtmlTableCell();
HtmlTableCell tableCell2 = new HtmlTableCell();
HtmlTableCell tableCell3 = new HtmlTableCell();
HtmlTableCell tableCell4 = new HtmlTableCell();
tableCell1.Attributes.Add("class", "col1");
tableCell2.Attributes.Add("class", "col2");
tableCell3.Attributes.Add("class", "col3");
tableCell4.Attributes.Add("class", "col4");
tableCell1.Controls.Add(_description);
tableCell2.Controls.Add(_cost);
tableCell3.Controls.Add(_heaFunded);
/*if (ShowAddRow || ShowRemoveRow) {
Button addNewButton = new Button();
addNewButton.Text = (ShowAddRow) ? "Add Row" : "Remove";
if (ShowAddRow) {
addNewButton.Click += new EventHandler(addNewButton_Click);
}
if (ShowRemoveRow) {
addNewButton.Click += new EventHandler(removeButton_Click);
}
tableCell4.Controls.Add(addNewButton);
}
else{*/
tableCell4.InnerHtml = " ";
//}
Controls.Add(tableCell1);
Controls.Add(tableCell2);
Controls.Add(tableCell3);
Controls.Add(tableCell4);
}
/*void addNewButton_Click(object sender, EventArgs e) {
if (AddNewRow != null) {
AddNewRow();
}
}*/
/*void removeButton_Click(object sender, EventArgs e) {
if (RemoveNewRow != null) {
RemoveNewRow(this);
}
}*/
protected override void RecreateChildControls() {
EnsureChildControls();
}
public override void RenderBeginTag(HtmlTextWriter writer) {
writer.Write("<tr>");
}
public override void RenderEndTag(HtmlTextWriter writer) {
writer.Write("</tr>");
}
}
Controls, custom or otherwise that require a ViewState and wish to receive events should be created in Init.
Http is stateless. Your entire page with all its controls is recreated on every postback. Controls that you add in the design view, are added to your designer.cs file, and created for you. When you add controls yourself, you must write code to recreate the controls on every PostBack that occurs later.
You can use the session to remember which controls were added by code and add them on later PostBacks.

Customize Label, TextBox and RequiredFieldValidator Web Control problem on rendering

I've created a customize web control with the combination of a Label, TextBox and RequiredFieldValidator. To done this, I create a class Field that inherit a Table Control.
namespace WebHRIS.Controls
{
public class Field : Table
{
private Label lblField;
private TextBox tbField;
private RequiredFieldValidator rfvField;
private string _text;
private string _invalidMessage;
private string _clientScript;
private string _controlID;
public virtual string LabelText
{
get { return _text; }
set { _text = value; }
}
public virtual string InvalidMessage
{
get { return _invalidMessage; }
set { _invalidMessage = value; }
}
public virtual string ClientScript
{
get { return _clientScript; }
set { _clientScript = value; }
}
public virtual string ControlID
{
get { return _controlID; }
set { _controlID = value; }
}
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
TableRow tr = new TableRow();
TableCell tc = new TableCell();
lblField = new Label();
lblField.Text = _text;
tc.Controls.Add(lblField);
tr.Cells.Add(tc);
tbField = new TextBox();
tbField.ID = _controlID + this.ID;
tc = new TableCell();
tc.Controls.Add(tbField);
tr.Cells.Add(tc);
rfvField = new RequiredFieldValidator();
rfvField.ControlToValidate = tbField.ID;
rfvField.ErrorMessage = this.InvalidMessage;
rfvField.EnableClientScript = (this.ClientScript.ToLower() != "false");
tc = new TableCell();
tc.Controls.Add(rfvField);
tr.Cells.Add(tc);
this.Rows.Add(tr);
}
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
lblField.RenderControl(writer);
}
}
}
This is how I used this control
<%# Register TagPrefix="udc" Namespace="WebHRIS.Controls" Assembly="WebHRIS" %>
<udc:Field ID="fSample" runat="server" LabelText="Sample : " InvalidMessage="ErrorMessage"
ClientScript="false" ControlID="tb" />
Note that this is only a partial code. Now, I'm having a problem like this.
I want to eliminate the 'Sample : ' text. T.I.A
At a glance, I think you're getting the second line of text in you Render method:
protected override void Render(HtmlTextWriter writer)
{
base.Render(writer);
lblField.RenderControl(writer);
}
lblField is the Label control - I would bet that the Label is getting written a second time by the call to lblField.RenderControl(writer). Try removing that line and see if your control will render properly.

Categories

Resources