I have a class UserPane l: Panel. I do so.
private bool AutoSize_ = true;
public bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
But when I change Autosize_ still returns are always true. How to make that value correctly transmitted.
The Panel class already have a property AutoSize.
You define a new Property with the same name. Check your warnings, you must have the following :
warning CS0114: 'UserPanel.AutoSize' hides inherited member 'System.Windows.Forms.Panel.AutoSize'. To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
When you are calling the AutoSize property of UserPanel, you are in fact calling the property of the superclass Panel. So your field AutoSize_ will never get changed.
Act accordingly to the warning :
public class UserPanel : Panel
{
private bool AutoSize_ = true;
public override bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
}
On a side note, why do you want to change the already working AutoSize functionnality? Are you sure this is what you need?
You need to override the property, because it is already defined in Panel.
public override bool AutoSize {
get {
return base.AutoSize;
}
set {
base.AutoSize = value;
}
}
Isn't the compiler giving you the warning over this?
If you are doing something like this.
public partial class myPanel : Panel
{
private bool AutoSize_ = true;
public bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
}
You are hiding Panels AutoSize property. You should override this property. You can override it to return the base value (which actually does not do much).
public override bool AutoSize
{
get
{
return base.AutoSize;
}
set
{
base.AutoSize = value;
}
}
Or maybe you can do some custom work there.
public override bool AutoSize
{
get
{
//return custom value
}
set
{
//set some custom value
}
}
If you have that class
class P : Panel
{
bool AutoSize_ = true;
public bool AutoSize
{
get
{
return AutoSize_;
}
set
{
AutoSize_ = value;
}
}
}
And then you create an instance and change the value of AutoSize like this:
var p = new P();
p.AutoSize = true;
This should work fine (at least in my tests), the problem arise when you do something like this:
var p2 = (Panel)p;
p2.AutoSize = false; // this change the AutoSize property of the Panel not the property of the derived class P
If this isn't your case then no idea what happens.
Related
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;
}
}
I want to get value of TextBox in Form1, to another class.
I try to make a set and get, but I can't do this, because VS shows me error about ambiguity in code.
public partial class Form1 : Form
{
private TextBox _textBox1;
public Form1()
{
this._textBox1 = textBox1;
InitializeComponent();
}
public string _textBox1
{
get { return _textBox1.Text; }
set { _textBox1.Text = value; }
}
}
How to make this correct? My control is private.
You have one field and one property in you class with the same name, change the name of the property, for instance to
public string FormTextBox1
{
get { return _textBox1.Text; }
set { _textBox1.Text = value; }
}
as naming standard the public properties must be Pascal Case notation
Capitalization Conventions
You can pass textBox1.Text to a variable, and make a getter/setter for it.
Like this:
public class A : Form1
{
// assuming it's a string. If it's not, change the type
// for the getter method below accordingly
private string textBoxValue;
// at some point, you'll have to make this line below:
textBoxValue = textBox1.Value;
public string GetTextBoxValue()
{
return textBoxValue;
}
}
public class B
{
A aReference = new A();
// you can get the value you want by doing
// aReference.GetTextBoxValue();
}
public void yourFormLoadMethod()
{
//this instantiates a new object of your class
nameOfYourClass newYourObject = new nameOfYourClass(//put any params you need here);
txtNameOfYourTextBox.DataBindings.Add("Enabled", newLTDObjectBenInt, "YourTextBoxEnabled", true, DataSourceUpdateMode.OnPropertyChanged);
txtNameOfYourTextBox.DataBindings.Add("Value", newLTDObjectBenInt, "YourTextBoxEntered", true, DataSourceUpdateMode.OnPropertyChanged);
txtNameOfYourTextBox.DataBindings.Add("Visible", newLTDObjectBenInt, "YourTextBoxVisible", true, DataSourceUpdateMode.OnPropertyChanged);
}
public class nameOfYourClass
{
//constructor
public nameOfYourClass(//same params here from the Load method)
{
//place any logic that you need here to load your class properly
//this sets default values for Enable, Visible and the text
//you use these fields to manipulate your field as you wish
yourTextBoxVisible = true;
yourTextBoxEnabled = true;
yourTextBoxEntered = "this is the default text in my textbox";
}
private bool yourTextBoxEnabled;
public bool YourTextBoxEnabled
{
get
{
return yourTextBoxEnabled;
}
set
{
yourTextBoxEnabled = value;
}
}
private bool yourTextBoxVisible;
public bool YourTextBoxVisible
{
get
{
return yourTextBoxVisible;
}
set
{
yourTextBoxVisible = value;
}
}
private string yourTextBoxEntered;
public string YourTextBoxEntered
{
get
{
return yourTextBoxEntered;
}
set
{
yourTextBoxEntered = value;
}
}
}
How do you set default value for setter getter? I want to do some operations while setting the setter.
public bool spin {
get { return this.spin; }
set {
if (value == false) this.spinBack = true;
this.spin = value;
}
}
private bool spinBack;
I tried this on Unity3D and got this error when trying to do so.
StackOverflowException: The requested operation caused a stack
overflow.
I tried just setting the getter and leave getter as default like so
public bool spin {
get;
set {
if (value == false) this.spinBack = true;
this.spin = value;
}
}
private bool spinBack;
but I get this error
'spin.get' must have a body because it is not marked abstract, extern,
or partial
The StackOverflowException is due to your this.spin = value; line which is recursively setting spin.
Use a backing field instead:
public bool Spin
{
get { return _spin; }
set {
if (value == false) this.spinBack = true;
_spin = value;
}
}
private bool _spin;
private bool spinBack;
I have my Control.When I change the properties of the control. I get this:
this.myLabel1.BorderShadow = true;
this.myLabel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
And I need to get this:
this.myLabel1.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.myLabel1.BorderShadow = true;
How to do so is done automatically in Form.Desinger.cs ?
If you say Why?
private bool BorderShadow_ = false;
public bool BorderShadow
{
get
{
return BorderShadow_;
}
set
{
if (Border_Style_ == BorderStyle.FixedSingle)
{
BorderShadow_ = value;
}
else
{
throw new ArgumentOutOfRangeException("BorderShadow", "BorderShadow can be true if BorderStyle=FixedSingle");
}
}
}
You could look into the ISupportInitialize interface. It allows you to skip the validity check when initializing your controls. For example (adapted from one of my projects):
public class MyControl : Control, ISupportInitialize
{
private bool _created = true;
public void BeginInit()
{
_created = false;
}
public void EndInit()
{
_created = true;
//check all your properties here too
}
private bool BorderShadow_ = false;
public bool BorderShadow
{
get
{
return BorderShadow_;
}
set
{
BorderShadow_ = value;
if (_created && Border_Style_ != BorderStyle.FixedSingle)
throw new ArgumentOutOfRangeException();
}
}
}
If I remember correctly, the VS designer will automatically add calls to BeginInit and EndInit for you as well.
I think they will appears in the same order as they are defined. So you can override with new old setting:
public new BorderStyle BorderStyle
{
get {return base.BorderStyle;}
set {base.BorderStyle = value;}
}
and then declare your BorderShadow setting.
The designer will always order the properties alphabetically and this can't be changed.
The sense of a property is that it is side effect free and that it can be changed at any time in any order. This means that if you have multiple properties which representing some kind of complex state and not all combinations are making sense, this error should not be reported while switching the property itself.
So to accomplish these problems you have two possibilities:
Like #Andrew already mentioned implement ISupportInitialize and take care if you are within this state.
Within the property setter call a method that checks if all settings currently made are making sense and perform the desired action only in this case:
public class MyControl : Control
{
private bool _BorderShadow;
private BorderStyle _BorderStyle;
public bool BorderShadow
{
get { return _BorderShadow; }
set
{
if(_BorderShadow != value)
{
_BordeShadow = value;
ApplyBorderShadowIfNeeded();
}
}
}
public BorderStyle BorderStyle
{
get { return _BorderStyle; }
set
{
if(_BorderStyle != value)
{
_BorderStyle = value;
ApplyBorderShadowIfNeeded();
}
}
}
private void ApplyBorderShadowIfNeeded()
{
if(_BorderStyle == BorderStyle.FixedSingle
&& _BorderShadow)
{
// ToDo: Apply the shadow to the border.
}
}
}
I want to add property's to my custom control like above example property with descriptions!
I don't know hot to display that with GUI like above.
I want to know what attribute to use it.
private bool IsNum = true;
[PropertyTab("IsNumaric")]
[Browsable(true)]
[Description("TextBox only valid for numbers only"), Category("EmSoft")]
public bool IsNumaricTextBox
{
set
{
IsNum = value;
}
}
protected override void OnKeyPress(KeyPressEventArgs e)
{
base.OnKeyPress(e);
if (IsNum)
{
doStruf(e);
}
}
private void doStruf(KeyPressEventArgs e)
{
if (!System.Text.RegularExpressions.Regex.IsMatch(e.KeyChar.ToString(), "\\d+") && !char.IsControl(e.KeyChar))
e.Handled = true;
}
I want to display this as property tool box with Description
Like This in property box
IsNumaric True
The property requires a Getter in order to be displayed in the property grid:
private bool isNum = true;
[PropertyTab("IsNumaric")]
[Browsable(true)]
[Description("TextBox only valid for numbers only"), Category("EmSoft")]
public bool IsNumaricTextBox {
get { return isNum; }
set { isNum = value; }
}
It is quite easy to achieve, you just have to decorate it with an attribute like in the sample below:
[PropertyTab("IsNumaric")]
[DisplayName("NumericOrNot")]
[Category("NewCategory")]
public bool IsNumaricTextBox
{
set
{
IsNum = value;
}
}
and to make it work you need following using:
using System.ComponentModel
If you do not specify Category - property will show under Misc category (please note, that by default properties are being shown by names, not by categories). In this example the property is going to be shown under NewCategory and the name of the property is going to be NumericOrNot.