I have a textBox, textBoxQuery, in window QueryWindow.
I need to access textBoxQuery's Text in another window, MainWindow.
I have the following accessor in QueryWindow:
public string QueryString
{
get { return textBoxQuery.Text; }
set { textBoxQuery.Text = value; }
}
And I attempt to use it in MainWindow:
cmdLine += QueryString;
However, I am thrown a CS0120 error. "An object reference is required for the nonstatic field, method, or property."
I have also attempted to implement the following method in QueryWindow:
public string queryString()
{
return textBoxQuery.Text;
}
Then using the following in MainWindow:
cmdLine += QueryWindow.queryString();
But none of the above worked.
I have searched through Google, but none of the solutions I found seemed to work. What is the correct way of accessing a control's properties from another window/class?
Oh!
The assessor is used to access an instance of a class (an object) of type QueryWindow!
Basicly, you could create a bunch of query windows (each would be their own instance) by doing this:
QueryWindow myQueryWindow1 = new QueryWindow();
myQueryWindow1.show()
QueryWindow myQueryWindow2 = new QueryWindow();
myQueryWindow2.show()
// Note, the shows are only needed to make instances visible to the user.
For as long as you have the reference to myQueryWindow1 or myQueryWindow2, you can use an acessor to get the state of the instance:
string myString = myQueryWindow1.queryString();
So QueryWindow.queryString() wouldn't work, because there is no way for the program to tell which instance of QueryWindow you want!
Hope this helps!
Related
Main.cs contains variables and (as User Control) buttons, to increase value of variables.
Form1.cs is a primary Form, with methods and timers.
Graph.cs is only to draw form.
Main.cs
private int money;
private int income;
public string MoneyLabel
{
get { return moneyLabel.Text; }
set { moneyLabel.Text = value; }
}
Form1.cs
public Main start = new Main(100, 40, 0, 0);
...
start.Money += start.Income;
...
main1.MoneyLabel = start.Money.ToString();
...
Everything works fine here. Now I am trying to convert value, from moneyLabel with property MoneyLabel, and put it on graph.
Graph.cs
Main main1 = new Main();
...
if (int.TryParse(main1.MoneyLabel, out a))
{
throw new Exception(main1.MoneyLabel);
}
That exception provides message with "0" value.
MoneyLabel is increasing every second with integer, but I am not able to convert that value back.
It always gives 0 as result.
I tried with multiple convert declarations: Parse, TryParse, Convert.ToInt32 etc.
Full code: https://github.com/aescaesse/Csharp-codes/tree/master/firsttry
In the Form1 class at line 48 you should inject the main1 instance of Main at line47.
Then in the Economy class constructor you should inject it to the InitializeComponent which create a Graph instance at line 37 were you should inject the main instance.
Then you use the instance there instead of create a new Main instance and it will work.
If I understand your code correctly, MoneyValue property, returns the Text from Label, but I guess, when you increase Money property, you forgot to set the Text of Label as Money value. It should be handled in setter, or by using INotifyPropertyChanged Interface.
Regards
I'm using c# and Visual Studio. I want to access a variable from another form. I've found some things like:
textBox1.Text = form22.textBoxt17.Text;
But I don't want to access a textBox value, I just want to access a variable. I've tried this:
string myVar1 = Form2.myVar2;
But that doesn't work.
Any help?
Update
This is what I've got now:
private string _firstName = string.Empty;
public string firstName
{
get
{
return _firstName ;
}
set
{
if (_firstName != value)
_firstName = value;
}
}
In formLogin (where the variable is located), just below public partial class formLogin : Form
Then, later in code, inside button on click event:
OleDbCommand command2 = new OleDbCommand();
command2.Connection = connection;
command2.CommandText = "select firstName from logindb where username = '" + txtUsername.Text + "' and password = '" + txtPassword.Text + "'";
firstName = command2.ExecuteScalar().ToString();
I write this in formAntonyms (from where I want to access the variable) in formLoad event:
formLogin fli = new formLogin();
lblName.Text = fli.firstName;
The problem with all this is that, when formAntonyms opens, lblName is still empty, instead of showing the users name. What am I doing wrong, I've done all the steps right...
You are on the right path, you should not expose controls or variables directly to client code.
Create a read only property in the form/class you want to read the value from:
//Form2.cs
public string MyVar{get{ return textBoxt17.Text;}}
Then, being form22 the instance variable of your already loaded Form2 form class. Then, from any client code that has a reference to it, you can read the value of the property:
string myVal = frm22.MyVar;
EDIT:
Ok based in your last comment, you have a variable in Florm1 and want to access it from Form2, the principle is the same as the previous example, but instead of exposing a control property you now expose a private variable, and instead of living in Form2 it now lives in Form1:
//Form1.cs
private string _myVar = string.Empty
public string MyVar
{
get
{
return _myVar ;
}
set
{
if(_myVar != value)
_myVar = value;
}
}
The property is now read/write so you can update its value from client code
//From From2, assuming you have an instance of Form1 named form1:
string val = form1.MyVar;
...
form1.MyVar = "any";
First of all it is bad object oriented design to access variables from classes directly. It reduces maintainability and reusability.
Your problems arise, because the functionality of your objects is not clear to you.
You should not think in terms of "I want the value of this variable", but in terms of: "Suppose you have a form22, what properties should such a form have?".
Well, apparently it has a size and a position and lots of others, and apparently your form has some information that it displays, and you think that users of this form want to know the text of the displayed information.
Let's suppose the displayed information is named MyInformation. Be aware, that you can only display a description of the information. This descriptive text is not the information itself.
A proper object oriented design of your form would be
class Form22 : Form
{
public string MyInformationText {get {return ...; }
...
}
Now you are communicating to the users of Form22 that a Form22 has some MyInformation. You also communicated that you are not willing to share this information, only to share a descriptive text of the information. Furthermore users of your form can't change this information.
This gives you a lot of advantages. For instance, suppose you don't want to display the text in a TextBox, but in a ComboBox. Or maybe you don't want to display it at all anymore. The users of the form who wanted a descriptive text of MyInformation don't have to change.
Of course your design could be different if you want users of your form to change the information. Probably that would also mean that you need to change the displayed description of your information. But again: users of your form won't need to know this. Again, this gives you the freedom to change it without users having to change:
public MyInformation SpecialInformation
{
get {return this.mySpecialInformation;}
set
{
this.mySpecialInformation = value;
this.UpdateDisplay(mySpecialInformation);
}
}
It depends on your model if you should still provide a property for the displayed text or not: Should all MyInformation object in the world have the same displayed text, or could it be that the displayed text in form22 might differ from the displayed text of MyInformation in form23? The answer to this influences whether MyInformation should have a function to get the descriptive text, or whether the forms should have a function to get the descriptive text.
These are just examples to show that you should think in: what should my object do? What should users of my object be capable to do with my objects. The more you allow them to do, the less you will be able to change. You will have the greatest flexibility if you supply them with no more information than required. Besides you'll need to test much less functionality.
When coding in Visual Basic, I'm able to define triggers to variables like: Whenever the value of the variable is changed, this triggers a function, which in turn changes the value of another variable. I wonder if there is a way to do the same in C#; that is, I want to define a trigger to a variable, fired every time when the value of that variable is changed.
Below code is how I do it in VB. When running this App, whenever a new user logs in, the App assigns the username like ActiveUserName = "SomeUserName", and this in turn automatically updates the FormMain.StatusLabelUserName.Text in the form. So, is there a way to achieve this trigger in C#?
Public Property ActiveUserName() As String
Get
ActiveUserName = FormMain.StatusLabelUserName.Text
End Get
Set(ByVal Value As String)
FormMain.StatusLabelUserName.Text = Value
End Set
End Property
I believe you're looking for Properties
private int localMember;
public int publicProperty
{
get
{
return localMember;
}
set
{
localMember = value;
//Do whatever you want here.
}
}
The "get" block is run any time you access the value. The "set" block is run any time you assign a value.
This is handled by raising events. This post describes how to do it well.
This is a simple property. Here's the C# syntax:
public string ActiveUserName
{
get { return FormMain.StatusLabelUserName.Text; }
set { FormMain.StatusLabelUserName.Text = value; }
}
Properties can work the same in C#
public string ActiveUserName
{
get{ return FormMain.StatusLabelUserName.Text;}
set{FormMain.StatusLabelUserName.Text = value; /*do more stuff here; */}
}
This can get rather messy and somewhat rigid however. You may consider using events to accomplish the same thing.
Use INotifyPropertyChanged event.
Properties and the set brackets.
INotifyPropertyChanged could be implemented for WPF databindings for exemple.
I added a new property to a component to uniquely identify every gridcontrol in my project, called GridIdentifier:
public class MyCustomGridControl : GridControl
{
private string gridIdentifier = "empty";
[Browsable(true)]
[DefaultValue("empty")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string GridIdentifier
{
get { return gridIdentifier; }
set { gridIdentifier = value; }
}
public MyCustomGridControl()
{
if (this.gridIdentifier == "empty")
this.gridIdentifier = Guid.NewGuid().ToString();
}
}
The problem is that for existing controls in my forms, the form only serializes the new property after I change something (read: anything) within the form. It might be the caption of the form, the size, etc.
But what I would like to see is that it detects that the form has changed when I open it, so I can save it and the new property gets serialized.
Does anyone have a clue why the new property doesn't get saved after opening the form and how to fix it? Any other ideas that help are of course also appreciated.
I would guess it is doing basic sanity checking (i.e. should anything have changed) - to prevent unexpected source code changes (I hate it when opening a file can cause side-effects - I'm looking at you, DBML!).
On a side note, to force serialization generally (I don't think it will apply due to the above):
public bool ShouldSerializeGridIdentifier() { return true; }
the bool ShouldSerialize*() and void Reset*() are a convention used by the framework.
I'm trying to update textedit control through the Client class object databindings with INotifyPropertyChanged implementation and i can't get it to work. The object behind (datasource) updates but the textedit still remains blank. If i type the text into the editbox the datasource gets updated. Would you help please? Here's the relevant code i'm using:
public class Client : NotifyProperyChangedBase
{
private string _firstname;
public string Firstname
{
get
{
return this._firstname;
}
set
{
this.CheckPropertyChanged<string>("Firstname", ref _firstname, ref value);
}
}
}
public Client ClientA = new Client();
Binding fname = new Binding("Text", ClientA, "Firstname", true, DataSourceUpdateMode.OnPropertyChanged);
ultraTextEditor_firstname.DataBindings.Add(fname);
ClientA.Firstname = "testN"; <== editbox remains blank ...
Am I missing something here? Thanks in advance, Peter.
I am assuming your base is implemented something along the lines of this example. If I am incorrect in my assumption, you will need to provide the implementation of your NotifyProperyChangedBase class.
You may also want to review the Binding(String, Object, String, Boolean, DataSourceUpdateMode) constructor documentation, as it discusses the control events the binding attempts to locate.
Looking at that example, you will want to try something like this:
System.ComponentModel.BindingList<Client> bindings = new System.ComponentModel.BindingList<Client>();
Client clientA = bindings.AddNew();
clientA.Firstname = "John";
textEditControl.DataSource = bindings;
// This change presumably will be refelected in control
clientA.Firstname = "Jane";
Update:
After reviewing the documentation on the Add method of the ControlBindingsCollection class; I believe that the data source of the Binding needs to implement the IListSource interface in order to properly participate in the binding (all MSDN examples are DataSet or DataTable which implement this interface).