Store font of button in the constructor - c#

I have a customized button deriving from System.Windows.Forms.Button:
(class MyButton : Button)
This button has an extra property called IsSelected.
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
if (value)
this.Font = new Font(_storedFont.FontFamily, _storedFont.Size - 1); //Decrease font size by 1
else
this.Font = _storedFont; //Set font back to origin
}
}
If IsSelected is set true the font size of the button will be decreased by 1 point to show the user of the application, that this button is in "pressed" state.
If IsSelected is set false the font size of the button will be set back to original size to show the user that this button is now again in "normal" state.
The issue is now that I first need to store the original font size that has been set in the properties window in Visual Studio, before it is changed by IsSelected.
To hold the stored original font size I have property called StoredFont (class level field = _storedFont).
I then tried to store the original font size in a chained constructor in MyButton, but it appears that the constructor is called before Visual Studio has actually set the font that has been defined in the properties window.
Question 1:
Is it correct that the constructor is called before Visual Studio actually sets the font?
Question 2:
Any suggestions to how to save the font that has been set from the properties window when a new instance of MyButton is created?
Note!
I have already considered many other possibilities to show selected state (CheckBox instead of Button, other back color etc.), and this is not my question.
Thanks a lot in advance!

Question 1: Yes otherwise you'll endup with a NullReferenceException...
Question 2: Assuming the first Font assignment is the font you want to store, you could store the font in an override of Font
public override Font Font
{
get
{
return base.Font;
}
set
{
if(_storedFont == null)
_storedFont = Font;
base.Font = value;
}
}
This way you don't have to worry about the order of initialization.

Related

How to control serialization of visual desinger properties in Xamarin for iOS

In Xamarin for iOS, I have a view which inherits from UIView, that is set up as follows:
[Register("BorderView"), DesignTimeVisible(true)]
public partial class BorderView : UIView, IComponent
{
...
[Export("BorderStyle"), Browsable(true)]
public BorderStyles BorderStyle
{
get { return this.borderStyle; }
set { this.borderStyle = value; }
}
...
private BorderStyles borderStyle = BorderStyles.All;
...
}
Where BorderStyles is an enum set up as follows:
public enum BorderStyles : int
{
All = 0,
Top = 1,
Bottom = 2,
None = 3
}
The issue I am having is in the visual designer (IDE is Visual Studio for Windows). For the most part, setting the Border Style property works as intended; however, if the default value of All is specified, the designer immediately reverts to whatever non-default value was previously set (e.g., Top, Bottom, or None as depicted below). Selecting "Default Value" from the drop-down will result in All being selected, however this seems non-intuitive to me and indicates that perhaps I am missing something.
Is there a way to control serialization in the Xamarin visual designer for iOS?
I would like it to be such that selecting All would save to the property value, without having to remember to select the designer-synthesized "Default Value" option (which gets converted to All).

How to set variable color for a Windows Forms color property

I'm a beginner, and I think that the solution is very simple, but I can't find it all over the Internet.
I'm looking for a way of setting the back color of forms and controls to a certain color variable so if I change its value to green for exapmple, every control that its back color set to mainColor will turn green and that the changes will show up in the designer.
public class MainForm:Form
{
public static Color mainColor=[some color];
public static Color secColor=[some color];
public Main()
{
InitializeComponent();
BackColor=mainColor;
control1.BackColor=secColor;
control2.BackColor=secColor;
control3.BackColor=secColor;
}
}
Like that by changing mainColor and secColor. The controls are changed, but it wont show up in the designer. What is the right way of doing it?
Use the Colors class.
public static Color redColor = Colors.Red;
public static Color greenColor = Colors.Green;
public static Color blueColor = Colors.Blue;
public static Color whiteColor = Colors.White;
Here is a pallete of the available colors:
If you want to create a new color, use Color.FromArgb();
Check out this answer for more information on new colors.
Yes, that is called DataBinding, and it's done partly with the Designer and partly with code.
Instead of declaring
public static Color mainColor=[some color];
declare it as a property:
public Color MyColor
{
get
{
return myColor;
}
set
{
myColor = value;
}
}
In your main form, edit each of the controls that you want to be influenced by this variable to bind their color property to it. I'll use a Panel as the sample control, so add some Panel objects to your form. Then in each Panel object, in the Properties panel, click the + next to DataBindings, then click in the empty box next to (Advanced). Click the ellipsis (...) and select the BackColor property. Then, under the Binding dropdown, select Add Project Data Source. Select Object in the next dialog and navigate to your form, and select that. A list of properties will then appear in the Formatting and Advanced Binding dialog box and you can select your property MyColor.
Note that once you have created this data source for the first one, you won't need to recreate it for each Panel - just reference the one you created already.
You can then change the BackColor of any of the controls you did this databinding on by changing the value of the MyColor property in your program. They will all change together.
You will probably also need to arrange that property to broadcast the message that it has changed, so add this line to the set() method.
form1BindingSource.ResetBindings(false);
so that the set method looks like this.
set
{
myColor = value;
form1BindingSource.ResetBindings(false);
}
That tells the binding source object to notify all subscribers to update themselves, and it will happen automatically every time the MyColor property is changed.

Set taskbar icon of top level usercontrol (Winforms)

I have a top level (ie. acts like a window) UserControl (.NET 4.0) which I am using to simulate a custom form. I can easily set the title text and taskbar text like so:
public override string Text
{
get { return base.Text; }
set
{
base.Text = value
TitleText.Text = value;
}
}
Which sets both the title text and taskbar text:
Please note that the bar down the bottom of the image is my actual taskbar; I have installed an alternate shell
The problem I have come across is that I can't seem to set the taskbar icon of this UserControl as it has no overridable Icon property so I can't set the taskbar icon as I would with the text. Please also note that the icon shown in the UserControl is just a PictureBox containing an image.
So, in short I want to be able to do this:
But I can't do this as there is no Icon property for a UserControl:
public override Icon Icon
{
get { return base.Icon; }
set
{
base.Icon = value;
TitleBarIcon.Image = value.ToBitmap();
}
}
How can I change the taskbar icon?
Thanks in advance ;)
I am not sure if I got you right but I think you have to possibilites:
Either set the Icon of the ParentForm.
Or set the ApplicationIcon as described here: http://msdn.microsoft.com/en-us/library/339stzf7.aspx
EDIT:
As you are using a control as TopLevelControl you need to send the WM_SETICON during the creation of the control - as the form does!
Taken from the Form.CreateHandle:
Icon icon = this.Icon;
if (icon != null && this.TaskbarOwner.Handle != IntPtr.Zero)
{
UnsafeNativeMethods.SendMessage(this.TaskbarOwner, 128, 1, icon.Handle);
}

How-To set Height of a Textbox?

For my single line Textbox, I set is Border = None. On doing this, the height turns very small. I can't programamtically set the height of the textbox. If I set any border, then again its fine, but I don't want any border. Even the text is not visible completely - so the font size is already bigger the the textbox height.
I tried creating a custom textbox, and set the Height of it, but it has no effect. How to handle this situation? Any help is highly appreciated.
There is a simple way not to create a new class.
In Designer.cs file:
this.textBox1.AutoSize = false;
this.textBox1.Size = new System.Drawing.Size(228, 25);
And that's all.
TextBox derives from Control, which has an AutoSize property, but the designers have hidden the property from the PropertyGrid and Intellisense, but you can still access it:
public class TextBoxWithHeight : TextBox {
public TextBoxWithHeight() {
base.AutoSize = false;
}
}
Rebuild and use.
TextBox controls automatically resize to fit the height of their Font, regardless of the BorderStyle you choose. That's part of the defaults used by Visual Studio.
By changing the Multiline, you can override the Height.
this.textBox1.Font = new System.Drawing.Font("Microsoft Sans Serif",
26.25F,
System.Drawing.FontStyle.Regular,
System.Drawing.GraphicsUnit.Point,
((byte)(0)));
this.textBox1.Location = new System.Drawing.Point(373, 502);
// this is what makes the height 'stick'
this.textBox1.Multiline = true;
// the desired height
this.textBox1.Size = new System.Drawing.Size(100, 60);
Hope this helps.
I just created this case in an empty project and don't see the result you are describing.
When the BorderStyle is none, the display area of the Textbox auto-sizes to the font selected. If I then set Multiline = true, I can change the height portion of the Size property and the change sticks.
Perhaps another portion of your code is modifying the height? A resize event handler perhaps?
My suggestions:
Post the relevant portions of your code
Try to reproduce the issue in an empty WinForms project (as I just did)
I find the best solution is to subclass the Textbox and expose the hidden AutoSize there:
public class TextBoxWithHeight : TextBox
{
public bool Auto_Size
{
get { return this.AutoSize; }
set { this.AutoSize = value; }
}
}
Now you can set the Autosize on or off using the object inspector in the visual designer or in code, whatever you prefer.
Just select your textbox and go to properties then increase your font size.. DONE !!!

Change the Textbox height?

How do I change the height of a textbox ?
Neither of the below work:
this.TextBox1.Size = new System.Drawing.Size(173, 100);
or
this.TextBox1.Size.Height = 100;
I wanted to be able to change the single line text box height to fit a font size on it without using multi-line if possible.
Go into yourForm.Designer.cs
Scroll down to your textbox. Example below is for textBox2 object.
Add this
this.textBox2.AutoSize = false;
and set its size to whatever you want
this.textBox2.Size = new System.Drawing.Size(142, 27);
Will work like a charm - without setting multiline to true, but only until you change any option in designer itself (you will have to set these 2 lines again).
I think, this method is still better than multilining. I had a textbox for nickname in my app and with multiline, people sometimes accidentially wrote their names twice, like Thomas\nThomas (you saw only one in actual textbox line). With this solution, text is simply hiding to the left after each char too long for width, so its much safer for users, to put inputs.
There are two ways to do this :
Set the textbox's "multiline" property to true, in this case you don't want to do it so;
Set a bigger font size to the textbox
I believe it is the only ways to do it; the bigger font size should automatically fit with the textbox
You can set the MinimumSize and/or the MaximumSize properties of the textbox. This does not affect the size immediately, but when you resize the textbox in the forms designer, the size will automatically be adjusted to satisfy the minimum/maximum size constraints. This works even when Multiline is set to false and does not depend on the font size.
Just found a great little trick to setting a custom height to a textbox.
In the designer view, set the minimumSize to whatever you desire, and then completely remove the size setting. This will cause the designer to update with the new minimum settings!
set the minimum size property
tb_01.MinimumSize = new Size(500, 300);
This is working for me.
Try the following :)
textBox1.Multiline = true;
textBox1.Height = 100;
textBox1.Width = 173;
Steps:
Set the textboxes to multiline
Change the height
Change the font size. (so it fit into the big textboxes)
Set the textboxes back to non-multiline
public partial class MyTextBox : TextBox
{
[DefaultValue(false)]
[Browsable(true)]
public override bool AutoSize
{
get
{
return base.AutoSize;
}
set
{
base.AutoSize = value;
}
}
public MyTextBox()
{
InitializeComponent();
this.AutoSize = false;
}
}
May be it´s a little late. But you can do this.
txtFoo.Multiline = true;
txtFoo.MinimumSize = new Size(someWith,someHeight);
I solved it that way.
AutoSize, Minimum, Maximum does not give flexibility. Use multiline and handle the enter key event and suppress the keypress. Works great.
textBox1.Multiline = true;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
e.Handled = true;
e.SuppressKeyPress = true;
}
}
You can put it inside a panel that has the same back color with your desired height. This way has this advantage that the text box can center horizontally, which is not provided by other solutions.
You can make it even more natural by using the following methods
private void textBox1_Enter(object sender, EventArgs e)
{
panelTextBox.BorderStyle = BorderStyle.FixedSingle;
}
private void textBox1_Leave(object sender, EventArgs e)
{
panelTextBox.BorderStyle = BorderStyle.None;
}
The Simplest Way to do that
Right click on the TextBox.
Go to properties.
Set Multiline = True.
Now you will be able to resize the TextBox vertically as you wish.
for me, the best approach is remove border of the textbox, and place it inside a Panel, which can be customized as you like.
The following code added in your constructor after calling InitializeComponent() will make it possible to programmatically set your text box to the correct height without a) changing the Multiline property, b) having to hardcode a height, or c) mucking with the Designer-generated code. It still isn't necessarily as clean or nice as doing it in a custom control, but it's fairly simple and robust:
if (txtbox.BorderStyle == BorderStyle.None)
{
txtbox.BorderStyle = BorderStyle.FixedSingle;
var heightWithBorder = txtbox.ClientRectangle.Height;
txtbox.BorderStyle = BorderStyle.None;
txtbox.AutoSize = false;
txtbox.Height = heightWithBorder;
}
I decided to make it cleaner and easier to use by putting it in a static class and make it an extension method on TextBox:
public static class TextBoxExtensions
{
public static void CorrectHeight(this TextBox txtbox)
{
if (txtbox.BorderStyle == BorderStyle.None)
{
txtbox.BorderStyle = BorderStyle.FixedSingle;
var heightWithBorder = txtbox.ClientRectangle.Height;
txtbox.BorderStyle = BorderStyle.None;
txtbox.AutoSize = false;
txtbox.Height = heightWithBorder;
}
}
}
Some of you were close but changing designer code like that is annoying because you always have to go back and change it again.
The original OP was likely using an older version of .net because version 4 autosizes the textbox height to fit the font, but does not size comboboxes and textboxes the same which is a completely different problem but drew me here.
This is the problem I faced when placing textboxes next to comboboxes on a form. This is a bit irritating because who wants two controls side-by-side with different heights? Or different fonts to force heights? Step it up Microsoft, this should be simple!
I'm using .net framework 4 in VS2012 and the following was the simplest solution for me.
In the form load event (or anywhere as long as fired after InitializeComponent): textbox.AutoSize = false Then set the height to whatever you want. For me I wanted my text boxes and combo boxes to be the same height so textbox.height = combobox.height did the trick for me.
Notes:
1) The designer will not be affected so it will require you to start your project to see the end result, so there may be some trial and error.
2) Align the tops of your comboboxes and textboxes if you want them to be aligned properly after the resize because the textboxes will grow down.
This is what worked nicely for me since all I wanted to do was set the height of the textbox. The property is Read-Only and the property is in the Unit class so you can't just set it. So I just created a new Unit and the constructor lets me set the height, then set the textbox to that unit instead.
Unit height = txtTextBox.Height;
double oldHeight = height.Value;
double newHeight = height.Value + 20; //Added 20 pixels
Unit newHeightUnit = new Unit(newHeight);
txtTextBox.Height = newHeightUnit;
You can make multiline : false and then just change the text size on the text box then the height will automatically increment
you can also change you can also change MinimumSize
So after having the same issue with not being able to adjust height in text box, Width adjustment is fine but height never adjusted with the above suggestions (at least for me), I was finally able to take make it happen. As mentioned above, the issue appeared to be centered around a default font size setting in my text box and the behavior of the text box auto sizing around it. The default font size was tiny. Hence why trying to force the height or even turn off autosizing failed to fix the issue for me.
Set the Font properties to the size of your liking and then height change will kick in around the FONT size, automatically. You can still manually set your text box width. Below is snippet I added that worked for me.
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Point(60,300)
$textBox.Size = New-Object System.Drawing.Size(600,80)
$textBox.Font = New-Object System.Drawing.Font("Times New Roman",18,[System.Drawing.FontStyle]::Regular)
$textBox.Form.Font = $textbox.Font
Please note the Height value in '$textBox.Size = New-Object System.Drawing.Size(600,80)' is being ignored and the FONT size is actually controlling the height of the text box by autosizing around that font size.
All you have to do is enable the multiline in the properties window, put the size you want in that same window and then in your .cs after the InitializeComponent put txtexample.Multiline = false; and so the multiline is not enabled but the size of the txt is as you put it.
InitializeComponent();
txtEmail.Multiline = false;
txtPassword.Multiline = false;
I think this should work.
TextBox1.Height = 100;

Categories