I have a numericupdown control on a C# Windows Form, and am interested in adding a leading zero to its value if it is < 10. (It is for the user to enter the minutes value of a time.)
I am not very familiar with overrides/inheriting yet in C# but it is looking as though I may have to do that.
It looks like this post on EggheadCafe has the answer I need. Is it as simple as making a new class and then creating a control of that new class?
public class TestNum : NumericUpDown
{
protected override void ValidateEditText()
{
if (base.UserEdit)
{
base.ValidateEditText();
}
}
protected override void UpdateEditText()
{
Text = Convert.ToInt32(base.Value).ToString("00");
}
}
When I try this, I am not sure how to create the new control that takes advantage of this class. I am using Visual Studio 2008. Still very new to windows forms. Thanks for any advice.
EDIT
I was able to make this work by editing the Designer-created code so that instead of the new control being of the original class, it was of the new one. So after adding the class above, I did the following (these changes are in two different locations, but I am only showing the lines that mattered):
Changed:
this.numTest = new System.Windows.Forms.NumericUpDown();
private System.Windows.Forms.NumericUpDown numTest;
To:
this.numTest = new SampleForm.TestNum();
private TestNum numTest;
Why not just use a DateTimePicker control? Set its ShowNumericUpDown property to true and set its Format property to Custom and set the CustomFormat property to hh:mm:ss.
Perhaps this will be useful for you.
You need to use this newly created class in your form. It doesn't replace all NumericUpDown controls, it's a subclass.
Add the project which contains this class to the toolbox (Tools->Toolbox Items... - if memory serves) and you should be able to drag the control onto the form where you want to use it.
Stumbled across this by looking for "NumericUpDown Display Hex with Leading Zero's"
public class HexNumericUpDown : System.Windows.Forms.NumericUpDown
{
public HexNumericUpDown()
{
Hexadecimal = true;
}
protected override void ValidateEditText()
{
if (base.UserEdit)
{
base.ValidateEditText();
}
}
protected override void UpdateEditText()
{
Text = System.Convert.ToInt64(base.Value).ToString("X" + HexLength);
}
[System.ComponentModel.DefaultValue(4)]
public int HexLength
{
get { return m_nHexLength; }
set { m_nHexLength = value; }
}
public new System.Int64 Value
{
get { return System.Convert.ToInt64(base.Value); }
set { base.Value = System.Convert.ToDecimal(value); }
}
private int m_nHexLength = 4;
}
Use date time picker with following properties:
Format = Custom
CustomFormat = "hh:mm:ss"
ShowUpDown = True
Related
I'm currently creating a project in Visual Studio 2015 using C# in WinForms; I used the words "ToolBox items" to refer to dateTimePickers, textbox, labels etc. It is a really big project and it will save me a lot of time if I could drag and drop the objects and they already have format; for example the datetimePicker custom format, textbox align etc.
The issue is that I need to customize some properties of these objects. This far I have this piece of code that allows me to change some properties that are overridable.
public partial class MoneyBox : TextBox
{
public override Color BackColor
{
get { return Color.Azure;}
set { base.BackColor = value; }
}
}
But for other properties I cannot do this. Also I cannot inherit from an object already formatted because this object hasn't been initialized and I get null when inheriting. I also tried to customize the initialize component and the paint event of objects, but for some reason the changes don't show on the object.
public partial class DateTimePick : DateTimePicker
{
public void InitializeComponent()
{
InitializeComponent();
this.Format = DateTimePickerFormat.Custom;
this.CustomFormat = "dd/MM/yyyy";
}
}
Any ideas?
Thanks in advance!
Constructor is a suitable place to initialize properties of the control. For most properties, to initialize the control with custom values when you drop it on design surface, it's enough to set new values in constructor, for example:
public class MyDateTimePicker : DateTimePicker
{
public MyDateTimePicker()
{
this.Format = DateTimePickerFormat.Custom;
this.CustomFormat = "dd/MM/yyyy";
}
}
In some cases, for example for Text property, when you drop an instance of the control on design surface, the property is set in InitializeNewComponent method of the Designer of control.
This may not be exactly what you're looking for, I'm sure there is a better way of doing it, but this was my solution for default control properties. It makes a list of all controls in your form (and their child controls) and changes the properties on initialization.
public static void ChangeDefaultProperties(Control C)
{
var ControlQueue = new Queue<Control>();
ControlQueue.Enqueue(C);
while (ControlQueue.Count > 0)
{
Control Current = ControlQueue.Dequeue();
DefaultPropertiesOverride(Current);
foreach (Control c in Current.Controls)
{
ControlQueue.Enqueue(c);
}
}
}
public static void DefaultPropertiesOverride(Control C)
{
if(C is DateTimePicker)
{
((DateTimePicker)C).Format = DateTimePickerFormat.Custom;
((DateTimePicker)C).CustomFormat = "dd/MM/yyyy";
}
if(C is TextBox)
{
((TextBox)C).BackColor = Color.Azure;
}
}
Then just call ChangeDefaultProperties(this); in your main form initialization
I have created my custom UserControl with some custom properties for it. For example:
[Description("Example Description"),Category("CustomSettings"),DefaultValue("Transmedicom")]
public string DatabaseAddress
{
get; set;
}
Everything works fine. I can change custom property in code and in design-time.
What I'm looking for (and cannot find anything) now is: How could I repaint (reacreate) my UserControl in design-time when my custom property change in design-time.
Let's say when DatabaseName will be changed to localhost UserControl will add and display some Label on my UserControl. It's important to work in Design-Time.
Nothing special there. You just have to set the text to Label inside the property setter. That should update the UI.
private string databaseAddress;
[Description("Example Description"), Category("CustomSettings"), DefaultValue("Transmedicom")]
public string DatabaseAddress
{
get { return databaseAddress; }
set
{
databaseAddress = value;
yourLabel.Text = value;//Set value to Label or whatever
}
}
Try this
private string _databaseAddress = "localHost";
[Description("Example Description"), Category("CustomSettings"), DefaultValue("Transmedicom")]
public string DatabaseAddress
{
get
{
return _databaseAddress;
}
set
{
if(!string.IsNullOrEmpty(value))
{
_databaseAddress = value;
lblAddress.Text = value;
lblAddress.Invalidate();
}
}
}
Both previous answers are correct.
I just want to add that the user control can even react on resizing during design time, using the Layout event.
I am trying to create an inherited control that will have some default values that would save me some time since these controls are to be the same on each form.
I have created 2 class for this. A base class that Inherit UltraButton where I put the values that will be common to all the buttons. In this case the ButtonStyle, image size and the control size.
Here is the class :
public class BaseButton : Infragistics.Win.Misc.UltraButton
{
public BaseButton()
{
//We set the properties of the base object.
ButtonStyle = Infragistics.Win.UIElementButtonStyle.Popup;
ImageSize = new Size(32, 32);
Size = new Size(100, 62);
}
[Browsable(false)]
public new Size Size
{
get { return base.Size; }
set { base.Size = value; }
}
}
Now I need to create a Reset button (that inherits from BaseButton) that will specify the image to use for the ResetBt, the Text and the default anchoring for the control :
public class ResetBt : BaseButton
{
private readonly string _text;
public ResetBt()
{
Appearance.Image = Properties.Resources.Restart_32_32;
_text = "&Reset";
base.Anchor = AnchorStyles.Bottom | AnchorStyles.Right;
}
[Browsable(false)]
public override string Text
{
get { return _text; }
}
}
This is where I noticed a problem. If I try to change the Anchor setting at design-time I can but at run time the values passed to the constructor override anything that was input at design-time. That behavior is fine for the image of the button and the Text value but for other properties like Anchor this is not suitable.
What is the best approach to pass default values to some properties of an inherited control and still allow for their modification at design-time ?
Thanks for the help.
Maybe try additional constructors:
public BaseButton(Image image, Anchor anchor)
{
Image = image;
Anchor = anchor
}
public ResetBt(Image image,Anchor anchor): Base(Image image,Anchor anchor)
{
_text = "&Reset";
}
public partial class ThanglishToTamilGUI : Form
{
public string anz;
public ThanglishToTamilGUI()
{
InitializeComponent();
}
public void btnConvertToBraille_Click(object sender, EventArgs e)
{
anz = richTextBoxTamil.Text.ToString();
GUI.TamilToBrailleGUI c1 = new GUI.TamilToBrailleGUI();
c1.Visible = true;
}
}
I need to pass my richtextbox (richTextBoxTamil) content to variable call anz.
I am retrriving anz variable in other form as form load event:
private void TamilToBrailleGUI_Load(object sender, EventArgs e)
{
ThanglishToTamilGUI tt = new ThanglishToTamilGUI();
String apper = tt.anz;
richTextBoxTamil.Text = apper;
}
My Problem:
I am getting null values as result. Since if I assigned any values that invoked correctly.
public partial class ThanglishToTamilGUI : Form
{
public string anz = "Hai";
public ThanglishToTamilGUI()
{
InitializeComponent();
} ...
Here my ans value is passed as "Hai". But my requirement is to get what ever the content in the richTextBoxTamil and pass it to that public variable call anz. What went wrong here please help me.
Thank you.
This is the problem:
ThanglishToTamilGUI tt = new ThanglishToTamilGUI();
String apper = tt.anz;
How do you expect apper to ever be anything other than null? You're fetching the variable from a freshly-created form, which has never been shown, and which has never had btnConvertToBraille_Click called on it.
Presumably there's an existing ThanglishToTamilGUI object somewhere, and that's the one you want to fetch the variable from. Basically, one form needs to know about the instance of the other form.
(I'd also strongly suggest using a property rather than a public variable, but that's a different matter. You might not even need to have a separate variable at all - just declare a property which fetches richTextBoxTamil.Text.)
Alternatively, just pass the relevant string to the constructor of the new form:
public void btnConvertToBraille_Click(object sender, EventArgs e)
{
GUI.TamilToBrailleGUI c1 = new GUI.TamilToBrailleGUI(richTextBoxTamil.Text);
c1.Visible = true;
}
Then the new form doesn't need to know about the old form at all - it only needs to know the text to display.
(You might want to pull it out of the constructor and into a settable property, but it's the same basically principle: the code creating the form pushes the data, rather than the new form pulling it.)
You can create a public property to access the current Text value of the textbox.
public string RichTextBoxText
{
get
{
return richTextBoxTamil.Text;
}
}
The way you do it now the form is instantiated, but the click event is not fired. So there's no way you will get anything other than what you initialized the field to.
Load is not the place to look for user input. An event (like click) is where you need to check the property value:
private void SomeClick(object sender, EventArgs e)
{
String result = thanglishToTamilGUIObject.RichTextBoxText;
//do something with text
}
I have the following code that I'm trying to use to populate a ComboBox, but it's not showing the actual text of the objects that I'm adding.
internal partial class SortBox : UserControl {
private Field[] FieldReferences
...
internal Field[] Fields {
...
set {
this.FieldReferences = value;
this.cboFields.Items.Clear();
string NoneString = "(none)";
this.cboFields.Items.Add(NoneString);
this.cboFields.SelectedItem = NoneString;
foreach (Field Field in this.FieldReferences) {
MessageBox.Show(Field.ToString()); // <- This displays what I want displayed perfectly.
this.cboFields.Items.Add(Field);
}
}
}
...
}
public partial class Field : UserControl {
protected string LabelValue;
...
public override string ToString() {
return this.LabelValue;
}
}
Here's what I'm getting; they're all blank:
What am I doing wrong?
EDIT: Apparently, my Field class is inheriting from UserControl. I've done some tests, and it apparently has something to do with the fact that the class inherits from System.ComponentModel.Component.
If I am reading your code right, you are trying to put a usercontrol inside a combobox.
Overriding the ToString won't work when you do that, so to make the code that you currently have work, just change the DrawMode:
This works:
cboFields.DrawMode = DrawMode.OwnerDrawFixed;
cboFields.DrawItem += new DrawItemEventHandler(cboFields_DrawItem);
private void cboFields_DrawItem(object sender, DrawItemEventArgs e)
{
e.DrawBackground();
if (e.Index > -1)
e.Graphics.DrawString(cboFields.Items[e.Index].ToString(), e.Font, Brushes.Black, e.Bounds);
}
But I have to say, I don't know if putting a UserControl inside a ComboBox collection is the best way to do this. I would seriously consider refactoring that differently.
The items you add to the combo box should also be strings, just like in your message box.
Try: this.cboFields.Items.Add(Field.ToString());
Alternately, you can try setting the DisplayMember field, although ToString should already be the default:
this.cboFields.DisplayMember = "ToString()"