How to create custom TextBox control? - c#

I want to perform Trim() method on each TexBox control on my page, before value is returned. I dont' want to hard-code the same code for each TexBox control, I want to do it in more elegant way.
I've found made the following class
namespace System.Web.UI.WebControls
{
public partial class TrimmedTextBuox : TextBox
{
private string text;
public override string Text
{
get { return string.IsNullOrEmpty(text) ? text : text.Trim(); }
set { text = value; }
}
}
}
but it fails, while debuggind the compiler doesn't get inside get{} and set{}.
After that, I created a UserControl item, but it must be deriverd from System.Web.UI.UserControl, not System.Web.UI.WebControls.TextBox to get it work (there's an exception which points to that)
So, how can I do that ?

First you have to register your control in your .aspx page like that:
<%# Register TagPrefix="customControls" Namespace="WebApplication.Custom.Controls" Assembly="WebApplication"%>
Then you can call it using the markup
<customControls:TrimmedTextBuox ID="txtTrim" runat="server"/>
Plus you don't have to create another "text" property in your custom TextBox. Instead, it can be done like that:
namespace WebApplication.Custom.Controls
{
public class TrimmedTextBuox : TextBox
{
public override string Text
{
get
{
return base.Text;
}
set
{
if (!String.IsNullOrEmpty(value))
base.Text = value.Trim();
}
}
}
}

This will trim recursively all text boxes before inserting.
public static void trimRecursive(Control root)
{
foreach (Control control in root.Controls)
{
if (control is TextBox)
{
var textbox = control as TextBox;
textbox.Text = textbox.Text.Trim();
}
else
{
trimRecursive(control);
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
trimRecursive(Page);
}

Simple Solution to your problem is to hide the Text property of your base class by using new keyword. sample code...
public class TrimmedTextBox : TextBox
{
public new string Text
{
get
{
var t = (string) GetValue(TextProperty);
return t != null ? t.Trim() : string.Empty;
}
}
}
For more info about how new keyword with property works refrer to this SO Question

Related

Extended control value is not setting from UI

Hi I'm trying to extend the TextBox use that extends one in my code. in the extended control, By default, it will trim start and end.
the code I have tried
public class TextboxTrimSpaceing : TextBox
{
private string myVar;
new public string Text
{
get { return myVar; }
set { myVar = value.TrimEnd().TrimStart(); }//Control is not coming here
}
}
UI
<local:TextboxTrimSpaceing x:Name="TrimSpaceing" Text=" avi aaa "></local:TextboxTrimSpaceing>
var i = TrimSpaceing.Text; //Getting Null
Here why my control is not going to the setter and why I'm getting Null result
Note: it's displaying proper string in UI and I know I can maintain it in code. but I need like this.
If you want to trim the text, you could override the OnTextChanged method:
public class TextboxTrimSpacing : TextBox
{
private bool _trim = true;
protected override void OnTextChanged(TextChangedEventArgs e)
{
base.OnTextChanged(e);
if(_trim)
{
_trim = false;
Text = Text?.Trim();
_trim = true;
}
}
}
It makes no sense to define a new Text property.

Setting default size/text of custom control in c#

I am creating a custom control in my C# application in order to add a new property (MyProperty below). It is inheriting from Label. One thing I would like it to do, is display at a particular size when I drag it on to my form (200x132). I'd also like it to display no text. However, no matter how I try to do this, it doesn't seem to work. I am able to set BackColor and BorderStyle with no problem, however. I'm fairly new to C#, so maybe I'm missing something obvious.
Here is my code:
using System.Drawing;
using System.Windows.Forms;
namespace MyProgram
{
public enum MyEnum
{
Value1, Value2, Value3
}
public partial class MyControl : Label
{
public MyControl()
{
BackColor = Color.LightCoral;
BorderStyle = BorderStyle.FixedSingle;
AutoSize = false;
Size = new Size(200, 132);
Text = "";
InitializeComponent();
}
protected override void OnPaint(PaintEventArgs pe)
{
base.OnPaint(pe);
}
private MyEnum myProperty;
public MyEnum MyProperty
{
get { return myProperty; }
set { myPropery = value; }
}
}
}
The answer provided via Dispersia's link has a bug, in my opinion. The text reset should happen once and then whatever a user does after that shouldn't matter. In Dispersia's link you can't actually set the text back to the control name because it will keep blanking it out.
The answer provided by cramopy doesn't technically answer your question, it is a way to do it by using the defaults on a UserControl though. You'll also need to bind the Text property of the UserControl to the label's.
The following should work while inheriting from a Label and will only reset the Text property once.
public partial class MyControl : Label
{
#region fields
private IComponentChangeService _changeService;
private bool canResetText = false;
#endregion
#region properties
protected override Size DefaultSize
{
get { return new Size(200, 132); }
}
[Browsable(false)]
public override bool AutoSize
{
get { return false; }
set { base.AutoSize = false; }
}
public override ISite Site
{
get { return base.Site; }
set
{
base.Site = value;
if (!base.DesignMode)
return;
this._changeService = (IComponentChangeService)base.GetService(typeof(IComponentChangeService));
if (this._changeService != null)
this._changeService.ComponentChanged += new ComponentChangedEventHandler(this.OnComponentChanged);
}
}
#endregion
#region constructors
public MyControl()
{
base.BackColor = Color.LightCoral;
base.BorderStyle = BorderStyle.FixedSingle;
}
#endregion
#region methods
protected override void InitLayout()
{
base.InitLayout();
this.canResetText = true;
}
private void OnComponentChanged(object sender, ComponentChangedEventArgs ce)
{
if (ce.Component != null &&
ce.Component == this &&
ce.Member.Name == "Text" &&
base.DesignMode &&
this.canResetText)
{
((MyControl)ce.Component).Text = string.Empty;
this.canResetText = false;
if (this._changeService != null)
this._changeService.ComponentChanged -= new ComponentChangedEventHandler(this.OnComponentChanged);
}
}
#endregion
}
#Dispersia reply only answers the myControl1 thing. (deleted meanwhile)
Here comes a full guide for solving your problem:
Add a new UserControl named MyLabel
Change the following within Designer Mode:
BorderStyle:= FixedSingle
Size:= 200; 132
Now Drag&Drop a new Label onto the control
Edit those Label values (also within Designer Mode):
AutoSize:= false
BackColor:= LightCoral
Dock:= Fill
Text:= clear/empty this box!! (don't write this inside the box, you really have to clear it!)
TextAlign:= MiddleCenter
Just recompile your project && add a MyLabel control from the Toolbar.
Now it show up as you wanted!!

Trim all user input strings in ASP.NET Web Forms

I am looking for a way to trim all user input in ASP.NET without calling Trim() on every string instance. I came across extending the DefaultModelBinder for MVC. Is there a way to do this in web forms? What options are available? As a less desirable option, is there a way to incorporate this into the set method of a class?
You could create a custom TextBox which always returns a trimmed version of the text:
public class CustomTextBox : TextBox
{
public override string Text
{
get { return base.Text.Trim(); }
set { base.Text = value; }
}
}
Then just use this instead of the normal TextBox anywhere you need this behavior.
Here is the utility method to trim all TextBoxes in a page (or a parent control) recursively.
public static void TrimTextBoxesRecursive(Control root)
{
foreach (Control control in root.Controls)
{
if (control is TextBox)
{
var textbox = control as TextBox;
textbox.Text = textbox.Text.Trim();
}
else
{
TrimTextBoxesRecursive(control);
}
}
}
Usage
protected void Button1_Click(object sender, EventArgs e)
{
TrimTextBoxesRecursive(Page);
}
You have to call this extension method from the appropriate parent, e.g. Page.TrimTextControls
public static void TrimTextControls(this Control parent, bool TrimLeading)
{
foreach (TextBox txt in parent.GetAllControls().OfType<TextBox>())
{
if (TrimLeading)
{
txt.Text = txt.Text.Trim();
}
else
{
txt.Text = txt.Text.TrimEnd();
}
}
}

Change custom control default Text property at design time

I created a user control. It's basically a button with some custom properties.
public partial class CustomButton : Button {
// My custom properties, constructor and events
}
Everytime I add this CustomButton on a form, its default Text value is set to "customButtonX", where X is 1, 2, 3, ...
How can I change this value? I would like it to be "buttonX" (X = 1, 2, 3...).
EDIT : I would like the trick (or whatever it is I have to do) to be active when I add a button on a form via the design view also. Meaning when I drag-drop a CustomButton from my toolbox to a form, its Text value should be "buttonX".
The default is "yourControlNameX" thats right. But you can replace the name in the constructor.
Note that this only will work at Runtime (not at design time)
public partial class CustomButton : Button {
// My custom properties, constructor and events
public CustomButton()
{
this.Text = this.Text.Replace("customButton ", "button");
}
}
When you drag a control from the Toolbox to a form there are some events that are triggered. In your case you have to subscribe to the one that is fired when the text property of your control is changed from String.Empty to the default name and change it. To do this you have to get the service that exposes these events (an implementation of IComponentChangeService) before the control is added to the form. This can be done overriding the Site property of your control. Modifying the example that you can find here, this kind of code should work:
private IComponentChangeService _changeService;
public override System.ComponentModel.ISite Site
{
get
{
return base.Site;
}
set
{
_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
if (_changeService != null)
_changeService.ComponentChanged -= new ComponentChangedEventHandler(OnComponentChanged);
base.Site = value;
if (!DesignMode)
return;
_changeService = (IComponentChangeService)GetService(typeof(IComponentChangeService));
if (_changeService != null)
_changeService.ComponentChanged += new ComponentChangedEventHandler(OnComponentChanged);
}
}
private void OnComponentChanged(object sender, ComponentChangedEventArgs ce)
{
CustomButton aBtn = ce.Component as CustomButton;
if (aBtn == null || !aBtn.DesignMode)
return;
if (((IComponent)ce.Component).Site == null || ce.Member == null || ce.Member.Name != "Text")
return;
if (aBtn.Text == aBtn.Name)
aBtn.Text = aBtn.Name.Replace("customButton", "button");
}
Just override the text and set whatever you want into it.
public partial class CustomButton : Button {
public override string Text
{
get
{
//return custom text
return base.Text;
}
set
{
//modify value to suit your needs
base.Text = value;
}
}
}
May be you could use a ControlDesigner and set the Text property after inizialized.
public class MultiDesigner : ControlDesigner
{
public MultiDesigner()
{
}
public override void InitializeNewComponent(IDictionary defaultValues)
{
base.InitializeNewComponent(defaultValues);
ICommonControl control = this.Component as ICommonControl;
control.Text = control.Tag.ToString();
}
}
decorate your control with..
[Designer("MultiPuntoDeVenta.Controls.Tickets.Editors.Designer.MultiDesigner, MultiPuntoDeVenta.Controls")]
public class LabelBase<T> : KryptonLabel, ICommonControl where T : ICommonControl
{
.....

change label text in usercontrol at run time

hello
i m new to c# and im working on a project,in which i made a usercontrol1 as
*label textbox datepicker*now i wnt to change the label text,i m trying this code but it is not working
using System;
using System.Windows.Forms;
namespace library_system
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
// private string DateLabel
public string DateLabel
{
**get { return DateLabel.Text; }//error when i write dateLabel.Text
set
{
DateLabel.Text= value;//error datelabel.Text
}**
}
i m using this code in usercontrol for is it right to do this way??
and in the main form i m writing code as
userControl11.DateLabel="From Date";//on for load event??Is this Right
Thanks in advance!!
You are writing a property and setting itself.
If your label name is lbl you could simply use lbl.Text="what you want";
If you need a property to have a stronger check on text, you could write:
public string DateLabel
{
get { return lbl.Text; }
set { lbl.Text = value; }
}
So in main form you could write (suppose you have a control named uc)
uc.DateLabel = "hello";
EDITED
To be clear: suppose you have
one label named lbl in your UserControl1 user control
a UserControl1 control in your main form named uc
In your user control code you can write:
public string DateLabel
{
get { return lbl.Text; }
set { lbl.Text = value; }
}
In your main form you can then write:
uc.DateLabel = "what you want";
Try changing it to this (controlname is id you have given to your label)
public string DateLabel
{
get { return controlname.Text; }
set
{
controlname.Text= value;
}
}
Your Property is Called DateLabel, and you are trying to set it.
That doesnt make sense.
Try the following. You will need to drag a asp:Label onto you usercontrol and call it lblDateLabel.
public string DateLabel
{
get { return lblDateLabel.Text; }
set { lblDateLabel.Text= value; }
}

Categories