How to use common cs files to transfer variables between forms - c#

I am currently learning basics of c# window forms in visual studios and wondered how I use common cs files. I want to transfer variables from one file to another and I believe an easy way to do this is with a common cs file that just stores the variable and then i just reference it from each of the forms. So my questions are. How do i lay out the code for this common cs file ? if i reference the value in one form and then reference it in the next will it display the value recorded in the previous form or restart from 0. Thanks for any help!

A couple of things. I would remove the basic tag from this post, as that is a different language altogether and might elicit some weird responses.
Your question seems to confuse the cs file with objects and references. So first up, there is nothing magical about a .cs file. It is just a file where c# code is. Often there is a 1-class-per-file convention, but this is just a developer aid, not a requirement. Your data itself will be in an object instance, and that object instance is defined by a class (that happens to be in a cs file).
A simple class definition might look like this
public class Person
{
public int Id
{
get;
set;
}
public string Name
{
get;
set;
}
}
Then your first form can create an instance of a person like this:
Person bob = new Person();
bob.Id = 1;
bob.Name = "Bob Dylan";
(or perhaps you would be assigning values from a control)
You then need to pass your person object instance to your other form. There are several ways that can be done and without understanding your problem domain, I cannot make judgement on which would be most appropriate. But if your second form had a public Person property, you could do something as simple as
Form2 secondForm = new Form2();
secondForm.Person = bob;
secondForm.Show();
or passing via constructor (if that is how it is defined)
Form2 secondform = new Form2(bob);
secondForm.Show();
Now your secondForm instance can access that bob object created above, either via the Person property, or within the constructor depending on how you wrote it.
Whilst this could also be done using static classes or even singletons, I think that until you are completely clear about regular classes, the use of these has the potential to lead you into various "code smells".

Related

CS0118: "variable" is a variable but is used like a type

I have 2 cs files one named Heading and one named Accounts. There is a class in the Heading file named Heading and I want to use some of the methods in there in the Accounts cs file. I went to create an instance:
Heading heading = new Heading();
Then when I use the heading I don't have access to the Heading methods and I get the Error in the title. However I can use
Heading.GetThis();
I'm trying to find out why sometime I have to create an instance of another cs file and sometime I have to call the cs file class directly as I have in the same project another cs file called AccountName and there I had to create the instance
AccountName accountName = new AccountName();
Then I had uses of all the AccountNames methods.
Sorry if this didn't make since I tried to google this error but didn't see a solution for what i'm looking at.
To expand on the answer given in comments:
public class Heading
{
private Heading()
{
}
public static Heading GetThis()
{
return new Heading();
}
}
Code above creates the condition you explained. The Heading.cs is hiding its constructor to force its users to instantiate it in a specific way. There is a good chance that your Heading.cs is using singleton design pattern. If that is the case there should be a good reason for it.
This youtube video discusses what is singleton
Alternatives : use Heading.cs as intended by the its designer Heading heading = Heading.GetThis();. Or modify Heading.cs to
//make constructor public
public Heading()
{
}

On an asp.net Website, does each logged in user have their own instance "copy" of the source code being run?

I'm unsure how to word this question but I have a question regarding how asp.net and C# handle "instances" or "copies" of the source that runs and if there can be any sort of "cross pollination" between them when used by different users.
To summarise the question, can person A who is using the website at a particular time, get access to things that person B is doing if they are also on the website at the same time (this is what I want to avoid and confirm).
I understand how OOP works and this question is adding a layer on top of that to understand how isolated the code gets as will be described below.
For example, say there are 10 users who have signed up for a system with individual authentication (as created by VS).
And you have source code that you've written which performs various functions.
When person A uses the website and performs various operations, do they have their own "copy" of the source that's running for them?
If person B decides to use the website at the same time, do they also have their own "copy" of the source or are they using the same source that's also being used for person A?
As I understand it, every time you have a class and you instantiate it using a constructor, you have a new object of that item which is used and then destroyed later on when not needed.
Taking this thought one step above, does a user who's using the system have their own copy of the whole isolated source?
For example, there are static classes where there is only ever going to be 1 instance of it all the time. Does person A share the same static class as person B or do they each have their own static class?
Say for example, I have a class, which has global properties instead of method properties.
public partial class HelperMethods
{
private static string Item1 = "StaticString1";
private const string Item2 = "constString2";
private const string Item3 = "constString3";
public BlockingCollection<Task> Collection1 = new BlockingCollection<Task>();
public BlockingCollection<Task> Collection2 = new BlockingCollection<Task>();
public BlockingCollection<Task> Collection3 = new BlockingCollection<Task>();
public BlockingCollection<Task> Collection4 = new BlockingCollection<Task>();
public ApplicationUser CurrentUser { get; set; }
public HelperMethods(int id) {
using (var database = new DatabaseEntities()) {
CurrentUser = //database call here with ID.
}
}
}
Does user A and user B have their own separate copy of all these items (for example Collection1) or are these items shared between each other?
If user A adds items to Collection1, and at the same time user B adds items to Collection1, would they be adding the items to the same collection or would they be completely separate from each other?
So to simplify and summarise briefly what I am trying to understand, when user A and user B both log onto the website, do they each get a copy of "HelperMethods" (let's say HelperMethods is the whole program for simplicity) and is isolated from each other or does C# do something else where there's actually ever only one copy of HelperMethods and every user that uses the system just get the constructor method and share everything else that's in global parameters?
An image example would be as follows:
Scenario 1:
Person A
(Has copy of class HelperMethods and all items in it.)
Person B
(Has copy of class HelperMethods and all items in it.)
Scenario 2:
(HelperMethods - exposes all global parameters)
Person A (has copy of the HelperMethod constructor only.)
Person B (has copy of the HelperMethod constructor only.)
Thanks
The static members of the HelperMethods class will be shared across all users. They will not be separate for each request/user.
A static member is owned by the ASP.NET worker process, it is common for all users. The instance variables of course will be separate for each user.

Declaring And Calling Methods in Blue Prism Global Code Stage

I am a Blue Prism RPA Developer and I want to create methods in my global code and call them from other code stages. In Global code info page, it is stated that this could be done but i could not find a satisfactory resource on the subject.
Can anyone share a syntax rule set, maybe a sample global code and code stage code sniplets or guide me in the direction?
I use C# and i would much appreciate responses in C#
Note: I am not from a developer background, i have elementary coding know how but i am not entirely knowladgeable about OOP subjects (namely: Classes, Methods, Constructors, Inheritence etc)
I tried declaring one class and one method, that worked, i could call the method but when i tried to add new method and or class it failed, it did not compile with the overall code
If I understand your question correctly, you are looking for an example of a class containing one or more methods, that you can place into the Global Code stage of the Initialise page of your BP Object, and then be able to create/call instances of that class/method in your code-stages from the other pages in that BP Object.
I don't know how much you know, so I am going to assume every step needs to be explained.
Since you are using C#, your first stop should be the Code Options tab. Here you should reference any libraries you intend to use (.dll) on the top pane, and their respective namespaces in the bottom pane. BP already includes some basic ones as shown below. It is also very important to change the Language selection to C# (bottom left drop-down), as Visual Basic seems to be the default option:
Next, here is an example of a simple concrete class with some fields, a constructor, a property and a method. You can place this code inside the Global Code window as-is:
public class SomePerson
{
//Class variables
private string _firstName;
private string _lastName;
//Constructor
public SomePerson(string firstName, string lastName)
{
this._firstName = firstName;
this._lastName = lastName;
}
//Property
public string FullName
{
get
{
return string.Format("{0} {1}", this._firstName, this._lastName);
}
}
//Method
public string Hello()
{
string myText = "Hello "+FullName+", it is nice to meet you.";
return myText;
}
}
Now you will be able to call instances of this class from inside code-stages and use the property and the method. For example, you could supply the FirstName and LastName in a couple of data items in BP, and then use an instance of the SomePerson class property to get the FullName using this code:
SomePerson Anyone = new SomePerson(firstName, lastName);
fullName = Anyone.FullName;
Similarly, you could use the method as follows:
SomePerson Anyone = new SomePerson(firstName, lastName);
result = Anyone.Hello();
You could try all this out using a layout like this one:
And basically... that's it!. In this manner you can create as many classes (concrete or abstract) and interfaces as you need, just stack them up inside the Global Code pane as you did with this one.
Finally, make sure you understand that most VBOs (like the Excel one) are written in Visual Basic, so chopped-off stuff will not compile together with C# code; you must use one or the other. Yes, they are both .NET languages, but once you have chosen the BP Object language, you must write your code in that language.
A good example of a VBO with a global code could be MS Excel VBO. It contains several functions and methods.
Protected Function GetWorksheet(Handle As Integer, _
WorkbookName As String, _
WorksheetName As String) As Object
Return GetWorksheet(Handle,WorkbookName,WorksheetName,True)
End Function
or
Protected Sub CloseInstance(Handle As Integer, SaveWorkbooks As Boolean)
...
End Sub
And that code can be later used in Code Stages
Dim ws as Object = GetWorksheet(handle, workbookname, worksheetname)
CloseInstance(handle, savechanges)
Additionally, every Code Stage is actually a method and you can call it from other code stages.
For example, if we have a Code Stage called "Create Instance" in MS Excel VBO, that contains no inputs, and only one output (integer), then we can call it using this code:
Create_Instance(out)
That's also why the code stages names must be unique.

Avoiding magic strings and numbers

I am working on an application that has been edited by various programmers over the past few years and I have stumbled across a problem with using String Literals to access MenuItems.
For Example: in many places there is code like
mainMenu.MenuItems[1].MenuItems[0].Visible=true;
or
mainMenu.MenuItems["View"].MenuItems["FullScreen"].Visible=true;
how do I change the Strings used to identify the MenuItem and catch all of the places that it is being used for access? The menus and menuitems are declared as public and are used throughout this large application
What is the right way prevent the use of these magic indexes from being used. I forsee things being broken everytime a new item is added or the name is changed.
P.S. I have started using an enumerated dictionary approach in which every menuItem is paired with a key. but this still does not force other developers to use my implementation nor is it the most elegant solution to question 2
Give each menu item a name in the WinForms designer (I assume), and then refer to it by that name.
Then just use this in your code:
menuExit.Visible = false;
If the menu items are added programmatically, do this:
class MyForm : Form
{
private MenuItem menuExit;
...
myMenu.Items.Add(menuExit = new MenuItem(...));
...
}
and then still access it by the menuExit name. The key to avoiding magic numbers and strings is to just keep a direct reference to whatever it is you want to refer to. As a bonus, you can now rename this vairable safely using F2.
Romkyns answer is the correct one for this scenarion however if you do need to use string literals in your code I would alwasy keep them in public static classes such as:
public static class Constants
{
public static class Menu
{
public static readonly string FirstMenuName = "Menu 1";
...
}
public static class OtherCateogry
{
...
}
}
You can then access them by Constants.Menu.FirstMenuName.
As for definitively preventing other devs from using literals throughout code - you might have to make recourse to the Rod of Correction (sturdy metal ruler) ;).

Access/Set controls on another form

I'm not good at C# at all, I just don't get the logics. But VB I seem to understand alot better since it seems much more logical. Atleast to me.
So I'm run into something which isn't a problem at all in VB, accessing controls on a different form then the one you're currently in.
In VB, if I want to set the state of a button say, in Form2. I just type the following:
Form2.Button1.Text = "Text"
In C# I cannot seem to do this. Why? There must be a pretty good reason for this right?
Edit: So if I have this code, what would it look like to be able to access controls on the other form?
if (!AsioOut.isSupported())
{
SoundProperties.radioButtonAsio.Enabled = false;
SoundProperties.buttonControlPanel.Enabled = false;
SoundProperties.comboBoxAsioDriver.Enabled = false;
}
else
{
// Just fill the comboBox AsioDriver with available driver names
String[] asioDriverNames = AsioOut.GetDriverNames();
foreach (string driverName in asioDriverNames)
{
SoundProperties.comboBoxAsioDriver.Items.Add(driverName);
}
SoundProperties.comboBoxAsioDriver.SelectedIndex = 0;
}
Just tried to add this "SoundProperties SoundProperties = new SoundProperties();
And I do get access to the controls. But do I need to add this bit of code in both parts of this IF-statement? Seems like I do, but still, adding that line to the last part of this code doesn't do anything ang gives me the error message:
"A local variable named 'SoundProperties' cannot be declared in this scope because it would give a different meaning to 'SoundProperties', which is already used in a 'child' scope to denote something else"
Removing the line gives me the following error:
"An object reference is required for the non-static field, method, or property 'NAudio.SoundProperties.comboBoxAsioDriver'"
Here's the code after adding these lines in two places:
if (!AsioOut.isSupported())
{
SoundProperties SoundProperties = new SoundProperties();
SoundProperties.radioButtonAsio.Enabled = false;
SoundProperties.buttonControlPanel.Enabled = false;
SoundProperties.comboBoxAsioDriver.Enabled = false;
}
else
{
// Just fill the comboBox AsioDriver with available driver names
String[] asioDriverNames = AsioOut.GetDriverNames();
foreach (string driverName in asioDriverNames)
{
SoundProperties SoundProperties = new SoundProperties();
SoundProperties.comboBoxAsioDriver.Items.Add(driverName);
}
SoundProperties SoundProperties = new SoundProperties();
SoundProperties.comboBoxAsioDriver.SelectedIndex = 0;
}
Please don't hate me for saying this - but I think this is an issue that I've seen a lot of VB coders run into.
VB allows you to not deal with classes if you don't want to. When in C# you are adding a form to your project - visual studio is just making a class file for you that inherits from "Form".
In C# you have to actually instantiate this into an object and then work with that object. VB allows you to just access the class as if it was already instantiated - but it is actually just making a new "Form2" for you.
In vb if you want to have more than 1 actual "Form2" you would say something like this...
Dim window1 as new Form2()
Dim window2 as new Form2()
window1.Show()
window2.Show()
Now you will have two copies of "Form2" on your screen when you run this.
The difference between VB and C# is you also need to actually make(instantiate) your first copy of Form2 - C# will not do it for you.
Now to answer your question:
Once you have an actual object that has been instantiated - you need to actually make "Button1" public instead of private.
To do this - on Form2 - select Button1 and look at the properties...
Find the "Modifiers" property and set this to public.
You will now be able to see "Button1" on both window1 and window2.
Hope that helped.
You can access another form in c# too.
But you need a reference to the Form instance you want to interact with.
So you have to hold the variable of the 2nd Form instance and access it via this.
E.g.:
From the code of the first form call:
Form2 my2ndForm = new Form2();
my2ndForm.Button1.Text = "Text";
Be sure to set the access modifier of the Button1 to public or internal.

Categories