I have a class that has multiple properties. What I want to have is a value set to a particular property if there is no value passed to it. For instance, if txtFather.Text is blank, then the _theFather property of a class should have a default value of "N/A". Here is the code I have so far:
class StudentModel
private string _theFather = "N/A";
public string SetFather
{
get { return _theFather; }
set { _theFather = value; }
}
public void InsertStudent(StudentModel student)
{
MessageBox.Show(_theFather);
}
class AddStudent
private void button1_Click(object sender, EventArgs e)
{
var sm = new StudentModel()
{
SetFather = txtFathersName.Text
};
sm.InsertStudent(sm);
}
If I place a value in the txtFather.Text, I get the its value in the StudentModel Class but if I leave the txtFather.Text blank, I don't get the "N/A" value. I just get a blank or no value at all.
Thanks for your help.
I would encapsulate the logic within the StudentModel class by checking the value being passed to the setter, and only updating your backing field if the string is not null or whitespace.
public string SetFather
{
get { return _theFather; }
set {
if(!string.IsNullOrWhiteSpace(value))
{
_theFather = value;
}
}
}
This way you only have the logic in a single place. If you modify your class' consuming code, then you have to remember to change it everywhere.
You should set the property only if a string is typed, like this:
private void button1_Click(object sender, EventArgs e)
{
var sm = new StudentModel();
if (!string.IsNullOrEmpty(txtFathersName.Text))
sm.SetFather = txtFathersName.Text;
sm.InsertStudent(sm);
}
Related
I'm very new to c#, I started a few days ago, so please excuse me if it is basic.
I have two forms, the first one is like a login page, where someone enters their name. On my "Info.cs" class, it reads this name via a setter, into a variable, and my Getter called "GetCardName" returns this Name. I now made a new form where I want to access this name via the GetCardName getter, just dont know how too. Heres the code :
Here is some of the "info.cs" class code:
private string CardName { get; set; } = "";
public string GetCardName()
{
return this.CardName;
}
public void SetName(string name = "")
{
this.CardName = name;
}
And here is the code from the other form that is just trying to call GetCardName():
private void Form2_Load(object sender, EventArgs e)
{
lblWelcome.Text = Info.GetCardName();
}
When creating Form2 you need also pass it reference to the other form to get its properties.
So when creating and showing Form1 you should also create Form2 to pass that reference. Example (not tested) code:
var form1 = new Form1();
var form2 = new Form2(form1);
form1.Show();
and Form2 should be like:
public class Form2
{
private Form1 _form1;
public Form2(Form1 form1)
{
_form1 = form1;
// ... other initialization code
}
// ... other class declarations
}
General solution is: you need to persist reference to the Form1 being shown to the user and then pass that reference to Form2 whenever you create it.
You have two options :
you can create an instance of the class that you want to call
EX : Info infoVar = new Info(); (now you can use infoVar to call any methods of the Info.cs class)
you can make Info class a STATIC class (probably not what you want to do, but still helpful for the future perhaps) This makes it possible to call the info class directly without having to create a variable of that class but has some drawbacks. (more info here)
There is few ways to achieve what you want:
Public static property:
public class Info
{
public static string CardName { get; set; } = string.Empty;
}
You can access it or set value to it directly by:
private void Form2_Load(object sender, EventArgs e)
{
// Set
Info.CardName = "Some name";
// Get
lblWelcome.Text = Info.CardName;
}
Public non-static property:
public class Info
{
public string CardName { get; set; } = string.Empty;
}
You can access it or set value to it directly too, but need to create Info class instance before:
private void Form2_Load(object sender, EventArgs e)
{
Info info = new Info();
// Set
info.CardName = "Some name";
// Get
lblWelcome.Text = info.CardName;
}
Private static field with separated public static Get and Set methods:
public class Info
{
private static string cardName = string.Empty;
public static string GetCardName()
{
return cardName;
}
public static void SetCardName(string name = "")
{
cardName = name;
}
}
You can access GetCardName and SetCardName without creating Info class instance:
private void Form2_Load(object sender, EventArgs e)
{
// Set
Info.SetCardName("Some name");
// Get
lblWelcome.Text = Info.GetCardName();
}
Private non-static field with separated public non-static Get and Set methods:
public class Info
{
private string cardName = string.Empty;
public string GetCardName()
{
return cardName;
}
public void SetCardName(string name = "")
{
cardName = name;
}
}
You can access GetCardName and SetCardName after creating Info class instance:
private void Form2_Load(object sender, EventArgs e)
{
Info info = new Info();
// Set
info.SetCardName("Some name");
// Get
lblWelcome.Text = info.GetCardName();
}
Difference between fields and properties was pretty nice explained here: What is the difference between a field and a property?. In short, properties are "wrappers" over fields, which usually are private and you can't access to them directly or modify. It is a part of Member Design Guidelines. Also properties allow to add some validations through property setter to be sure that valid value is stored at cardName field, e.g.:
public class Info
{
private string cardName = string.Empty;
public string CardName
{
get => cardName;
set
{
// Check that value you trying to set isn't null
if (value != null)
cardName = value;
// Or check that name is not too short
if (value.Length >= 3) // Card name should be at least of 3 characters
cardName = value;
}
}
}
info myInfo=new info();
lblWelcome.Text = myInfo.GetCardName();
I want to assign one variable to another by reference so as when one variable updates so does the other.
I have a series of variables that I need to update based on something that a piece of hardware I am connected to is doing. I have set up an object array and am assigning each of my variables to an index in the object array. It is the object array that gets updated but when this happens I want the property setter for my original variable to fire so as I can do something. The reason for the object array is so as I can iterate through it in a loop and because my original variables can be of different types. I have shown an overly simplified version of what I am trying to do below, I hope it makes sense.
Edit: Just to note that the items in the testVars array are being updated elsewhere, I have just shown a simplified version of what I am trying to do below.
public partial class Form1 : Form
{
private bool _test0 = false;
private int _test1 = 0;
public object[] testVars = new object[2];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
testVars[0] = test0;
testVars[1] = test1;
}
public bool test0
{
get
{
return _test0;
}
set
{
_test0 = value;
UpdateTest0();
}
}
private void UpdateTest0()
{
bool NewTest0 = _test0;
}
public int test1
{
get
{
return _test1;
}
set
{
_test1 = value;
UpdateTest1();
}
}
private void UpdateTest1()
{
int NewTest1 = _test1;
}
}
One solution I thought might work for me was to use pointers but because the variable declaration and pointer creation must be in different scope in my application this will not work. Also everything I have read on forums has suggested that pointers should not be used.
# Michael Ceber, many thanks for the prompt response. I think I understand what you mean and have updated my example code accordingly but it still does not behave as I want. My updated code is as follows
namespace VariableLinks
{
public partial class Form1 : Form
{
private bool _test0 = false;
private int _test1 = 0;
public ObjectX[] testVars = new ObjectX[2];
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
testVars[0] = new ObjectX();
testVars[0].val = test0;
testVars[1] = new ObjectX();
testVars[1].val = test1;
}
public bool test0
{
get
{
return _test0;
}
set
{
_test0 = value;
UpdateTest0();
}
}
private void UpdateTest0()
{
bool NewTest0 = _test0;
}
public int test1
{
get
{
return _test1;
}
set
{
_test1 = value;
UpdateTest1();
}
}
private void UpdateTest1()
{
int NewTest1 = _test1;
}
private void button1_Click(object sender, EventArgs e)
{
testVars[0].val = true;
}
}
public class ObjectX : object
{
public object val = new object();
}
}
Now when my button click event fires and updates testVars[0].val I expect the setter for test0 to fire but it doesn't. I assume I have misunderstood what you meant?
If you store objects or reference types to objects in your array, i.e not value types like int, bool etc, which contain the values, then this will help.
e.g if your object 'objectx' has a property called value then objectx.value can store such a value.
Then you can set any variables you like to this objectx and whenever you update the value of objectx.value all variables will pickup the change, as they are all pointing to the same object...
So in your example
testVars[0] = test0;
testVars[1] = test1;
this would become
testVars[0].value = test0;
testVars[1].value = test1;
maybe to achieve this
public object[] testVars = new object[2];
should become
public ObjectX[] testVars = new ObjectX[2];
and add the single public property 'value' to this ObjectX class...
Hope that makes sense!
private string connectionName;
public string ConnectionName
{
get { return connectionName; }
set { connectionName = tbConnect.Text; }
}
After I enter value to Connect TextBox, ConnectionName property is returning null.
If I set my property as below, then I won't be able to use the property value publicly in my other classes.
public string ConnectionName
{
get { return connectionName; }
set { connectionName = value; }
}
private void btnTest_Click(object sender, EventArgs e)
{
ConnectionName= tbConnect.Text;
}
What would be the proper way to set ConnectionName property to use publicly?
After I enter value to Connect TextBox, ConnectionName property is
returning null.
Yeah, because you never set connectionName, but you are returning it in the ConnectionName getter. The following would create a property that sets/gets the value of the textbox:
public string ConnectionName
{
get { return tbConnect.Text; }
set { tbConnect.Text = value; }
}
If I set my property as below, then I won't be able to use the
property value publicly in my other classes.
No, that's not true, since ConnectionName is declared as public.
The correct way to implement this property would be either
private string connectionName;
public string ConnectionName
{
get { return connectionName; }
set { connectionName = value }
}
Or
public string ConnectionName { get; set; }
If you have a form where the user enters the connection name into a textbox, you should add an "OK", "Save," or "Apply" button to the form, and code its click handler like this:
protected void OK_Click(object sender, EventArgs e)
{
myObject.ConnectionName = tbConnect.Text;
}
... where myObject is a reference to an instance of the class that has the ConnectionName property.
I have 2 forms: Form A and Form B. I also have a property field class.
Form A contains the label I want changed when a property is changed. Form B contains code that will change the property field.
Property Class Code:
public class Controller
{
private static string _customerID;
public static string customerID
{
get { return _customerID; }
set
{
_customerID = value;
if (_customerID != "")
{
FormA.ChangeMe();
}
}
}
}
Form B Code:
private void something_Click(object sender, SomethingEventArgs e) {
Controller.customerID = "Cool";
}
Form A Code:
public static void ChangeMe()
{
var frmA = new FormA();
MessageBox.Show("Test: " + Controller.customerID); //This works! Shows Cool
frmA.lb2Change.Text = Controller.customerID; //This kind of works..
MessageBox.Show("Test2: " + frmA.lb2Change.Text); //This shows the correct value. Shows Cool
}
The property field value is passed (which I know from the MessageBox) however it does not update the value on the form label itself. Why is this? What am I doing wrong? I also believe there is a better alternative for achieving what ChangeMe() method is intended to achieve -- if so are there any suggestions?
You can do the following
To define a delegate
To Implement Property Change Notification
Delegate
public delegate void OnCustomerIDChanging(object sender,CancelEventArgs e);
public delegate void OnCustomerIDChanged(object sender,object value);
public class Controller
{
private static string _customerID;
public event OnCustomerIDChanging CustoerIDChanging;
public event OnCustomerIDChanged CustoerIDChanged;
public static string customerID
{
get { return _customerID; }
set
{
// make sure that the value has a `value` and different from `_customerID`
if(!string.IsNullOrEmpty(value) && _customerID!=value)
{
if(CustomerIDChanging!=null)
{
var state = new CancelEventArgs();
// raise the event before changing and your code might reject the changes maybe due to violation of validation rule or something else
CustomerIDChanging(this,state);
// check if the code was not cancelled by the event from the from A
if(!state.Cancel)
{
// change the value and raise the event Changed
_customerID = value;
if(CustomerIDChanged!=null)
CustomerIDChanged(this,value);
}
}
}
}
}
}
in your Form and when you are initiating the Controller Object
var controller = new Controller();
controller.CustomerIDChanging +=(sd,args) =>{
// here you can test if you want really to change the value or not
// in case you want to reject the changes you can apply
args.Cancel = true;
};
controller.CustomerIDChanged +=(sd,args) =>{
// here you implement the code **Changed already**
}
The above code will give you a great control over your code, also will make your controller code reusable and clean. Same
result you can get by implementing INotifyPropertyChanged interface
INotifyPropertyChanged
you might have a look on this article to get more information
In your static method ChangeMe you are creating a new Form every time, you want to Change the value. Instead of that you want to change the value of an existing form. Therefor your Controller needs an instance of this FormA. Try it like this:
public class Controller
{
//You can pass the form throught the constructor,
//create it in constructor, ...
private FormA frmA;
private string _customerID;
public string customerID
{
get { return _customerID; }
set
{
_customerID = value;
if (_customerID != "")
{
frmA.ChangeMe();
}
}
}
}
Now you donĀ“t need to be static in your FormA:
public void ChangeMe()
{
MessageBox.Show("Test: " + Controller.customerID);
this.lb2Change.Text = Controller.customerID;
}
I have a class called nyoba, i tried to enter value of textBox1.Text to eek.konsentrasi.
And I don't have any idea to call value of eek.konsentrasi from another class. Anybody knows? please help me.
public class nyoba
{
private string Konsentrasi;
public string konsentrasi
{
get
{
return Konsentrasi;
}
set
{
Konsentrasi = value;
}
}
public void njajal(string hehe)
{
}
}
private void button1_Click(object sender, EventArgs e)
{
nyoba eek = new nyoba();
eek.konsentrasi = textBox1.Text;
}
public class caller
{
//how to get eek.konsentrasi variable?
}
As first, your class names should always be pascal case (first letter uppercase). Also your public property should be pascal case.
Then your Nyoba class and its property Konsentrasi are not static, means you have to initiate the class as object before you can access it's non static property.
Nyoba n = new Nyoba();
string s = n.Konsentrasi;
To access the same instance you should not create the instance inside of the button click event. Place your Nyoba instance somewhere you can access to in the form and in the Caller class.