set new value to property in C# web form application - c#

I get this error on the setter line
"An unhandled exception of type 'System.StackOverflowException' occurred in WebFormsApplication1.dll"
What is an elegant way to manipulate Property1 which I added getter and setter for in a Master page (please see below),
then I attempted to manipulate it in method1() and finally call method1() inside onInit.
namespace WebFormsApplication1
{
public partial class SiteMaster : MasterPage
{
public string Property1
{
get
{
return System.Configuration.ConfigurationSettings.AppSettings["key1"];
//gets value from config file where pair key-value is stored
}
set
{
Property1 = value;
}
}
public void method1()
{
Property1 = Property1 + "stringToAppend"; // manipulate property here
}
protected void Page_Init(object sender, EventArgs e)
{
method1();
.....
}
}
}
In the Site.Master.aspx I have <%= Property1 %>
If I don't add the setter the property is read only. Maybe I should manipulate it inside the setter?
I was hoping to be able to do it separately for increased modularisation.
Thanks

the problem is here:
set
{
Property1 = value;
}
You can't do it because recursion occurs here and no condition to exit, you can't set this property in his own setter, you should have some field and set it in setter:
public string someValue = System.Configuration.ConfigurationSettings.AppSettings["key1"];
public string Property1
{
get
{
return someValue;
}
set
{
someValue = value;
}
}
Or you can use auto-property:
C# 6:
public string Property1 {get;set;} = System.Configuration.ConfigurationSettings.AppSettings["key1"];
Or lower than C# 6 - you should declare you property and initialize it in contructor or method:
public string Property1 {get;set;}
public void ConstructorOrMethod()
{
Property1 = System.Configuration.ConfigurationSettings.AppSettings["key1"];
}

Related

How to set set and get for Textbox control?

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;
}
}
}

C#: Make a field only modifiable using the class that contains it

I'm sure this has been asked before I just don't know the correct way to word it so I can't find what I am looking for.
I have a class with a field which I want to be able to see from the outside, just not be able to modify it directly..
public class myclass
{
public int value;
public void add1()
{
value = value + 1;
}
}
So I would really like to only have the 'value' field modifiable from the method add1() but I still want to be able to see the value of 'value'.
EDIT: I was thinking only modifiable via the class myclass, but I typed otherwise. Thanks for pointing that out.
public int value { get; private set; }
You cannot make it modifiable only by the method add1, but you can make it only modifiable by myclass.
See this:
https://msdn.microsoft.com/en-us/library/75e8y5dd.aspx
Please consider the following options to encapsulate a field (i.e. provide an "interface" for the private field value):
Provide the public method (accessor):
// ...
private value;
// ...
public void Add()
{
++value;
}
public int GetValue()
{
return value;
}
Provide the public property (only accessor):
// ...
private value;
// ...
public void Add()
{
++value;
}
public int Value
{
get { return value; }
}
Provide the auto-implemented property (public accessor, private mutator):
// ...
// The field itself is not needed: private value;
// ...
public void Add()
{
++Value;
}
public int Value { get; private set; }
It is worth noting that some IDEs or IDE–plugins provide the appropriate refactoring called "Encapsulate Field".
You can use public property without setter to just see the value from outside. make the value private so its only visible inside the calss.
public class myclass
{
private int value;
public void add1()
{
value = value + 1;
}
public int Value
{
get
{
return value;
}
}
}

how do i "link" to a property in another class

i have a class (say classA) that contains a string property.
i want to set it to a string property from another class (say classB) so that when i change the property into classA it changes in classB and visa versa.
i know i can do this with functions by using ref but when i try it on my class (Constructor) it doesn't work
here is what i have;
public class myClass
{
public string Name;
public int Image;
public myClass(ref string myName)
{
Name = myName;
}
public void changeIt()
{
Name = "xyz";
}
}
And my main code;
string myString = "abc";
Console.WriteLine("myString:"+myString);
myClass mClass = new myClass(ref myString);
mClass.changeIt();
Console.WriteLine("myString (After doThis):" + myString);
Console.ReadLine();
when i run it it produces;
myString:abc
myString (After doThis):abc
is there something i am missing here? why doesn't it change to xyz?
Generally speaking, a change in the state of an object should be communicated with an event.
So in the class that has the "important" property, when you change its value an event should be fired.
The other classes should be suscripted to this event and catch it.
You can add the value of the changed string to the fired event so that you won't even need to reference the object when the string value has changed.
You can see how events work in C# on this link.
An example of how to do it can be as follow:
class ClassWithImportantProperty
{
string myString = string.Empty;
public string MyImportantProperty
{
get { return myString; }
set
{
myString = value;
if (PropertyChanged != null)
PropertyChanged(myString, EventArgs.Empty);
}
}
public event EventHandler PropertyChanged;
}
class SecondClass
{
public string MyDependantString { get; set; }
public secondClass()
{
var classInstance = new ClassWithImportantProperty();
classInstance.PropertyChanged += classInstance_PropertyChanged;
}
void classInstance_PropertyChanged(object sender, EventArgs e)
{
MyDependantString = sender.ToString();
}
}
Basically you have a class that fires an event every time one of it's properties change.
Then another class that is suscribed to this event and every time it gets fired, it does some process of it's own.
Strings are immutable. What this means, is that when you "change" a string.. you're actually throwing away the old one and creating a completely new one. There is no getting around that without using some dodgy unsafe code. ("throwing away" in this context is.. forgetting about it.. allowing it to be cleaned up later by the Garbage Collector).
What this means in the context of your code, is that this:
Name = "xyz";
Creates a new string reference with the content xyz and assigns it to the reference Name. myString in the caller is unaffected by that.. it is a different reference.
As mentioned by #SimonWhitehead, strings are immutable. What you could do in this case, is to change your changeIt method to take an out parameter, and then pass in myString as the input, like so:
public void changeIt(out string myName)
{
myName = "xyz";
}
This will give you the output "xyz" after you make a call to this method as:
myClass.changeIt(out myString);
You are referencing a string into the constructor and changing its value in other method. So the ref keyword works only inside a block of code, constructor in this case.
This code will change the value myName to Name. But after constructor is called myName won't be referencing to a Name anymore. Note that you are assigning Name to ref myName and it won't reference to a Name.
public myClass(ref string myName)
{
myName = Name;
}
This will change the string as well:
public void changeIt(ref string myName)
{
Name = "xyz";
myName = Name;
}
I won't write about immutable because other guys already answered. You can do the trick with interfaces like so:
class Program
{
public interface IName
{
string Name { get; }
}
public class myClass : IName
{
public string Name { get; set; }
public myClass(string myName)
{
Name = myName;
}
public void changeIt()
{
Name = "xyz";
}
}
public class myClass2 : IName
{
private IName iname;
public string Name { get { return iname.Name; } }
public myClass2(IName myName)
{
iname = myName;
}
}
static void Main(string[] args)
{
myClass mClass = new myClass("abc");
myClass2 m2Class = new myClass2(mClass);
Console.WriteLine("myString:" + m2Class.Name);
mClass.changeIt();
Console.WriteLine("myString (After doThis):" + m2Class.Name);
Console.ReadLine();
}
}
It will actually do what you want to achieve.
To change the string, make the following changes in your code.
public string changeIt()
{
return "xyz"; //return a string from method
}
In the calling part
myString=mClass.changeIt(); //assign return value to myString

NotifyPropertyChanged through code

I have a class that contains two other objects.
A variable in the first object bind to WPF element, call it X.
A similar variable in the other object.
I want that when the PropertyChanged event happens, it will change the variable in the second object.
Here is the code that does not work for me:
The class that contains the variables: (I had register to property changed event)
private Class1 _var1;
public Class1 Var1
{
get { return _var1; }
set
{
_var1= value;
if (_var1!= null)
_var1.PropertyChanged += new PropertyChangedEventHandler(_var1_PropertyChanged);
else
_var1.PropertyChanged -= new PropertyChangedEventHandler(_var1_PropertyChanged);
}
}
void _var1_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(e.PropertyName=="X")
Var2.X= Var1.X;
}
private Class2 _var2;
public Class2 Var2
{
get { return _var2; }
set { _var2= value; }
}
Class 1:
private int _x;
public int X
{
get { return _x; }
set
{
if (_x!= value)
{
_x= value;
NotifyPropertyChanged("X");
}
}
}
class 2:
public int X { get; set; }
PropertyChanged work in class 1 but he did not come to an event I created in a class that contains the two variables, why?
I'm not sure I understand exactly what you mean, but if I had a class with 2 variables that I wanted to change together, I would try the following:
First, define some SetAndNotify method or you'll get a headache from the PropertyChanged events:
public void SetAndNotify<T>(ref T field, T value, Expression<Func<T>> exp)
{
if (!Equals(field, value))
{
field = value;
OnPropertyChanged(exp);
}
}
Add it to some base class that will handle this event.
Second, in your setter for Var1 you register for the change event and not set anything, is that on purpose?
Third and last, there's no problem with changing more than one property in a setter, but make sure it's the public property that you change:
private SomeType privateVar1;
public SomeType PublicVar1
{
get { return privateVar1; }
set
{
SetAndNotify(ref privateVar1, value, () => PublicVar1);
MyOtherPublicVar = someNewValue; // this will activate the property's setter.
}
}
I hope this helps. If not, please try to clarify your question.

Get/Set for a Private Static Collection?

I've defined a class with the following property:
private ObservableCollection<Job> allJobs;
Access is defined as follows:
public ObservableCollection<Job> AllJobs
{
get
{
return this.allJobs;
}
set
{
this.allJobs = value;
}
}
The get set works fine when I assign a whole ObservableCollection to the property, the set works fine for retrieving it obviously. But why have I lost all the methods that normally allow me to 'Add' (i.e. add 1 job to the collection)?
At the moment I'm having to create a temporary collection to populate to then assign to the allJobs property and I shouldn't have to.
Any ideas??
What do you mean with 'lost methods'? Have you tried AllJobs.Add()? The following code works for me:
void Main()
{
AllJobs = new ObservableCollection<Job>();
AllJobs.Add(new Job());
}
public class Job { }
private ObservableCollection<Job> allJobs;
public ObservableCollection<Job> AllJobs
{
get
{
return this.allJobs;
}
set
{
this.allJobs = value;
}
}
EDIT:
Based on your comment I've amended my code as follows but everything still works for me, I have noticed however that you don't seen to initialise the allJobs collection anywhere.
void Main()
{
PresentationManager.Instance.AllJobs.Add(new Job());
}
public class Job { }
sealed class PresentationManager
{
public static readonly PresentationManager Instance = new PresentationManager();
private PresentationManager()
{
allJobs = new ObservableCollection<Job>();
}
private ObservableCollection<Job> allJobs;
public ObservableCollection<Job> AllJobs
{
get { return this.allJobs; }
set { this.allJobs = value; }
}
}
Normally you wouldn't want a setter for such a property, as you would lose all events bound to the ObservableCollection when the setter is used.
public ObservableCollection<Job> AllJobs { get; private set; }

Categories

Resources