This question already has answers here:
Passing data between forms
(6 answers)
Closed 3 years ago.
I have List<Basket> sas = new List<Basket>(); in Form1.
And i need to output all values from this List in another form.
Edited: Now i have problem with outputing.
List<Basket> sas = new List<Basket>();
public Form1()
{
InitializeComponent();
foreach(Basket e in sas)
{
basketBox.Text += e.Name + Environment.NewLine;
}
}
I added elements in Form2, but when I try to output them in Form1 nothing happened.
There are several ways:
You can have the list as a static (global) variable in the form1 class and then use it in the other form.
Another solution would be to have a context class to be given to the other form when you construct it.
if by from you mean windows forms, then you can simply make your list public static, so you can have access to it everywhere.
If you are working with ASP.NET web forms then you probably should relay on your database.
PS: you can use the Singelton pattern or DI as well. but for the sake of simplicity stick with statics
Related
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".
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 5 years ago.
Improve this question
such a weird situation appears in front of me. Here is the thing.
If I would do this in PHP or some other programming language it would be easy but in C# I dont know how can I achieve this.
Brief description of my problem:
I have a UserForm in C# with combobox. In this combobox I have as many items as there are in the database -> so its dynamically filled on the start of the application
Each item should represent single UserForm. So here is the problem, if user choses item and clicks on button check should be fired if that userform has been created, if its not, then a new (object ?) userform must be created. Normally I would delete and recreate new form everytime user choses new option but I want to keep those Userforms and create them once and then only hide them or show them, so textinputs etc. remain filled while application will run (but I dont thing that creating 15-20 UserForms at the start of the app is okay in terms of performance).
So what I was thinking of doing and what I tried:
I wanted to use the name of chosen item from the combobox and use it as a Object (UserForm) name. (also perform check if it already exists before creating) -> apparently this is not possible in C# to use string variable as object name
I googled about Dictionaries, but can I store there whole UserForms ?
Also I was thinking of creating all 15-20 Userforms at the beginning and then looping through them and show them or hide them.
Any ideas ?
This is a caching problem. You want to cache the forms.
So first you need a container for the cache, e.g.
var cache = new List<UserForm>();
Then, when a form is needed, you need a special method to search the cache and add to it if needed. Because there is more than one type of form, you'll want to use generics here:
T GetOrCreateForm<T> where T: UserForm, new()
{
UserForm f = cache.OfType<T>().FirstOrDefault(); //Search cache
if (f == default(T)) //If not found,
{
f = new T(); //Create it anew
cache.Add(f); //and add it to the cache
}
return f; //return the form we just created/retrieved
}
You would then call this method, passing the type of the form desired:
var form1 = GetOrCreateForm<Form1>();
form1.Show();
The above assumes there is one type of form (one class) for each row in the list. If you actually have a common form class, but they are distinguished by something else (e.g. maybe each form has a unique Name property that is set at run time) then you'd need a dictionary to tell the forms apart:
var cache = new Dictionary<string, UserForm>();
UserForm GetOrCreateForm(string name)
{
UserForm f;
if (!cache.TryGetValue(name, out f))
{
f = new UserForm { Name = name };
cache.Add(name, f);
}
return f;
}
var myForm = GetOrCreateForm("SomeUniqueName");
myForm.Show();
This question already has answers here:
Communicate between two windows forms in C#
(12 answers)
Closed 3 years ago.
I have a table named questions with a field name qcategory. In WFA I have a ToolStripMenu where I have a category named Simulation and a sub-category named B. So, I want to create a mysql SELECT where to select only rows which values are equal with sub-category value. (Columns qcategory from table has value B). This is the string:
static string dataA = "SELECT DISTINCT * FROM questions order by rand() limit 1";
The only problem is that I have 2 forms. One with menu and one where I want to make that select.
You should try to split your UI-code and your database code. This is called Layering (MVVM, MVC, MVP,...) but you don't have to!
There are several ways:
1) Make a class that both forms can reference and execute your database logic there. (that would be the cleanest way for now)
2) Create an Event in your Form with the menu and react on it in the other Form
3) Your menu Form holds a reference to the other Form and executes a Method on it passing the selected subitem.
In code
1
public static class SqlClass
{
public static void ExecuteQuery(string menuItem)
{
//execute query
}
}
Form 1
//menu changed...
SqlClass.ExecuteQuery(menuItem)
2
Form1:
public event EventHandler<string> MenuItemChanged;
//menu changed...
if(this.MenuItemChanged != null)
this.MenuItemChanged(this, menuitem)
Form2:
public Form2(Form1 otherForm)
{
InitializeComponent();
_otherForm.MenuItemChange += //... handle your sql code
}
3
private readonly Form2 _otherForm;
public Form1(Form2 otherForm)
{
InitializeComponent();
_otherForm = otherForm;
}
//menu changed...
otherForm.ExecuteQuery(menuitem);
For the examples, Form 2 is the form where you want to execute your query because there is the Method/Event-Handler defined that will interact with your database.
To understand the solution, you need a more high level perspective - you get an information in code behind of a Form (a Class) and you want to consume that information somewhere else.
In general you need a reference to the Form that holds the information you are interested in and it tells you the information when changed (Event) OR
the information source tells every interested destination (calls a Method). Then the Information source hold the references to the consumers.
Both concepts are the same just the direction of the communication (and reference) changes.
The alternative (Option 1) is that you move your information destination somewhere else (e.g. in a static class) and consume it there. The Mechanism of passing the information is pretty much the same (via a parameterized Method call) but it encapsulates the UI-colde (Form) from the Database code (SQL query execution)
Learning C#:
I have structure of
form1 (splitcontainer)
userformLeft (button + sub-panel)
userformDisplay (loaded into panel in userformLeft)
userformRight
I want to execute a method in userformDisplay from form1 (timer in form1).
And the other way around, let's say I have public property form1.mainTimer, can
I call it from userFormDisplay like
myLong = this.parent.parent.mainTimer;
or similar.
yes.. you can do this:
myLong = ((form1)this.parent.parent).mainTimer;
Similar problems of communicating between one form and another... whether attaching to "events" of one, or calling / setting values to/from each other. Here are a couple links to questions I've answered to in the past that may help understand the relationships to do so.
Sample 1 with explicit steps to create two forms communicating back/forth to each other
Sample 2 somewhat similar, but attaching to events between forms
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.