Can´t add item to ListBox in different form - c#

I´m trying to build an application that can store different persons in a ListBox-control.
My ListBox-control is located in Form1 and so is this method that´s giving me some problem:
public void addPersonToList(Person person) {
string newPerson = person.firstName + " " + person.lastName + " " + person.age;
personList.Items.Add(newPerson);
}
In another Form, I call the addPersonsToList-method like this:
Form1 form1 = new Form1();
form1.addPersonToList(person);
Now, I´ve checked (while debugging) that the string newPerson in addPersonToList actually stores the correct string. The problem is that the string won´t show up in my ListBox(named personList).
Any suggestions?

Using new, you are creating a brand new instance of an item.
Form1 form1 = new Form1();
form1.addPersonToList(person);
So this code creates a new instance of Form1 and adds an item to that instance, which is probably not the one you are viewing. You somehow need a reference to the instance being displayed so you can reference that.

To reference an existing open form, do this:
foreach (Form frm in Application.OpenForms)
{
if (frm.GetType() == typeof(Form1))
{
Form1 frmTemp = (Form1)frm;
frmTemp.addPersonToList(person);
fromTemp.Dispose();
}
}
Similarly for MDI forms :
foreach (Form frm in MdiParent.MdiChildren)
{
}

Related

Calling forms list values. Ribbon1.cs and Form1.cs

I am developing a VSTO application. I have a button on Office Ribbon1.cs. and Form on Form1.cs. I call the form from the button creating a new form:
Form1 MallideVorm = new form Form1 (); // Create a form from Form1
MallideVorm.Show (); // Show the form
I have a list in my windows Form. I put strings in there:
foreach (Microsoft.SharePoint.Client.File file in fileCol)
{
str = file.Name;
// File.AppendAllText (# "C: \ install \ CSharp \ tulemus.txt", $ "File name: {str}" + Environment.NewLine); // for testing
foreach (form Form1 in System.Windows.Forms.Application.OpenForms)
{
if (frm.GetType () == typeof (Form1))
{
// RibbonDropDownItem ddItem1 = Globals.Factory.GetRibbonFactory (). CreateRibbonDropDownItem ();
//ddItem1.Label = $ "{str}";
Form1 frmTemp = (Form1) frm;
//ddList.Items.Add(ddItem1);
MallideVorm.addItemToListBoxFiles (file.Name);
}
}
}
All this is done with the Ribbon1.cs-s button. When I have a Form with a list, I would like to have in my Form1.cs: (to return the value that chosen)
private void FormFilesBox_SelectedIndexChanged (object sender, EventArgs e)
{string selectedFile = FormFilesBox.SelectedItem.ToString ();}
But that does not work. I think the problem is that I generate one Form A with the click of a button, but try to get values ​​from another Form B.
How can I define an action from Ribbon1.cs in Form1.cs or vice versa(FormFilesBox_SelectedIndexChanged). Or how can I refer to the one and same Form.
The answer on Cindy suggestion:
Thanks Cindy, but I don't know how to do that right. Word.interop has his own Globals Link?view=word-pia
So if I will make some public static class Globals {Form1 MallideVorm = new Form1(); } Then I will have errors like :
Severity Code Description Project File Line Suppression State
Error CS0117 'Ribbon1.Globals' does not contain a definition for
'ThisAddIn' 470 Active Or definition for Factory...
Abount the form code: I have Windows form In the Form1.cs Design.
In Form1.cs is:
public void addItemToListBoxFolder(string item)
{
FormFolderBox.Items.Add(item);
}
public void addItemToListBoxFiles(string item)
{
FormFilesBox.Items.Add(item);
}
private void FormFilesBox_SelectedIndexChanged(object sender, EventArgs e)
{
//_______________________________________________________Sharepoindist faili alla laadimine ja sealt avamine________________________________________
string selectedFile = FormFilesBox.SelectedItem.ToString();
//Here is the question, how to take value from other Form.
//In Ribbon1.cs it is declared as Form1 MallideVorm = new Form1(); //Creating form from Form1
// MallideVorm.Show();
var destinationFolder = #"C:\install\CSharp\TestkaustDoc";
ClientContext ctx = new ClientContext("https://Some/Some");
//Configure the handler that will add the header.
ctx.ExecutingWebRequest +=
new EventHandler<WebRequestEventArgs>(ctx_MixedAuthRequest);
//Set the Windows credentials.
ctx.AuthenticationMode = ClientAuthenticationMode.Default;
ctx.Credentials = System.Net.CredentialCache.DefaultCredentials;
// Get a reference to the SharePoint site
var web = ctx.Web;
// Get a reference to the document library
var list = ctx.Web.Lists.GetByTitle("Documents");
// Get the list of files you want to export. I'm using a query
// to find all files where the "Status" column is marked as "Approved"
var camlQuery = new CamlQuery
{
ViewXml = #"<View>
<Query>
<Where>
<Eq>
<FieldRef Name=""FileLeafRef"" />
<Value Type=""Text"">" + $"{selectedFile}" + #"</Value>
</Eq>
</Where>
</Query>
</View>"
};
camlQuery.FolderServerRelativeUrl = "/Some/Shared Documents/Test";
// Retrieve the items matching the query
var items = list.GetItems(camlQuery);
// Make sure to load the File in the context otherwise you won't go far
ctx.Load(items, items2 => items2.IncludeWithDefaultProperties
(item => item.DisplayName, item => item.File));
// Execute the query and actually populate the results
ctx.ExecuteQuery();
// Iterate through every file returned and save them
foreach (var item in items)
{
using (FileInformation fileInfo = Microsoft.SharePoint.Client.File.OpenBinaryDirect(ctx, item.File.ServerRelativeUrl))
{
// Combine destination folder with filename -- don't concatenate
// it's just wrong!
var filePath = Path.Combine(destinationFolder, item.File.Name);
// Erase existing files, cause that's how I roll
if (System.IO.File.Exists(filePath))
{
System.IO.File.Delete(filePath);
}
// Create the file
using (var fileStream = System.IO.File.Create(filePath))
{
fileInfo.Stream.CopyTo(fileStream);
}
}
}
I solved it using:
foreach (Form1 frm in System.Windows.Forms.Application.OpenForms)
Like that:
In Ribbon.cs I am creating a new Form:
Form1 MallideVorm = new Form1(); //Creating form from Form1
MallideVorm.Show(); // Showing form
Then using Application.OpenForms. (because the Form is one)
foreach (Form1 frm in System.Windows.Forms.Application.OpenForms)
{
if (frm.GetType() == typeof(Form1))
{
Form1 frmTemp = (Form1)frm;
frm.addItemToListBoxFiles(file.Name);
Then in Form1.cs the same way getting values from the ListBox.
foreach (Form1 frm in System.Windows.Forms.Application.OpenForms)
{
selectedFile = FormFilesBox.SelectedItem.ToString();
}

opening a form with a data inside it

I have 3 Forms: frmLOGIN, frmREGISTER & frmACCOUNTS
frmLOGIN has two buttons BtnRegister and BtnLogin, when I press BtnRegister it opens up frmREGISTER.
frmREGISTER has 1 button BtnAddAcc, BtnAddAcc is used to add a rows to datagridview(datagridview inside frmACCOUNTS)
frmACCOUNTS has only 1 datagridview inside it, nothing else
BtnRegister code (inside frmLOGIN)
frmREGISTER frm = new frmREGISTER();
frm.Show();
this.Hide();
BtnAddAcc code (inside frmREGISTER)
frmACCOUNTS acc = new frmACCOUNTS
acc.datagridview.Rows.Add(userID,ln,fn,Dateofbirth,address,contactnumber,username,password);
PROBLEM
When I register a user, using the code above, works, when I try to add code like acc.Show(); to open the form and see if it adds the row to the datagridview, and yes it really adds a row. Now when I get back to the login form and press BtnLogin to open up the frmACCOUNTS the datagridview rows are GONE
Reference
I will answer my own question
Answer is that you need to create a CLASS
Class Controller
{
public static frmLOGIN log = new frmLOGIN();
public static frmREGISTER reg = new frmREGISTER();
public static frmACCOUNTS acc = new frmACCOUNTS();
public static void FormOpen(string form_name)
{
if(form_name == "accounts")
{
acc.Show();
}
else if (form_name == "register")
{
reg.Show();
}
else if (form_name == "login")
{
log.Show();
}
}
}
now to use this. you do not need to call the form again inside the other forms you just need to call the class and and the call the form there.
example
let's say, I want to show login form
so I will call
Controller.FormOpen("login");
let's say I want to use the datagridview inside the Accounts form
and put it inside a new variable
Datagridview DGV = Controller.acc.Datagridview1
now you can use the datagridview inside the accounts form as DGV
Conclusion
call the form inside a class so when other forms wants to call/use another form they will be calling the same forms and not making a new one

Cant access Checkbox from another form

Any help is appreciated
Basically I am having trouble accessing a checkedlistbox on a tab.
I have a checkedlistbox on tab 1 of form 1. I want to pass this checkbox to form 2 and place the results in a listbox on form 2
Form1
public static void ShowResults(string strRoutine, string strCaption)
{
ResultsForm.Routine = strRoutine;
ResultsForm.Title = strCaption;
strXMLFileName = xmlDocConfig.SelectSingleNode("config/routine[#key='" + strRoutine + "']/outputfname").Attributes.GetNamedItem("value").Value;
strXMLFileName = clsUtilities.ReplacePathWildcards(strXMLFileName);
strXMLFileName = clsUtilities.ReplacePathWildcards(frmNSTDBQC.xmlDocConfig.SelectSingleNode("config/routine[#key='G']/outputfname").Attributes.GetNamedItem("value").Value) + "\\" + strXMLFileName;
ResultsForm.DisplayFile = strXMLFileName;
ResultsForm.ShowDialog();
}
In form 2 I can access the tab control, I can access QCForms.tcTabs.SelectedTab.Text with the correct result but QCForm.chkLstLines.Items.Count says 0 event though I have 10 Items checked
Form 2
public void frmResults_Load(object sender, EventArgs e)
{
int i = 0;
this.Text = "Results - " + this.Title;
switch (QCForm.tcTabs.SelectedTab.Text)
{
case "Line Checks":
i = 0;
while (i < QCForm.chkLstLines.Items.Count)
{
if ( QCForm.chkLstLines.GetItemChecked(i))
{
lstFeatures.Items.Add(QCForm.chkLstLines.Items[i].ToString()); // VB6.GetItemString(QCForm.chkLstLines, i));
}
i++;
}
}
}
Edit
Form 1
public static void ShowResults(string strRoutine, string strCaption)
{
var ResultsForm = new Form(this);
//ResultsForm.Routine = strRoutine;
//ResultsForm.Title = strCaption;
strXMLFileName = xmlDocConfig.SelectSingleNode("config/routine[#key='" + strRoutine + "']/outputfname").Attributes.GetNamedItem("value").Value;
strXMLFileName = clsUtilities.ReplacePathWildcards(strXMLFileName);
strXMLFileName = clsUtilities.ReplacePathWildcards(frmNSTDBQC.xmlDocConfig.SelectSingleNode("config/routine[#key='G']/outputfname").Attributes.GetNamedItem("value").Value) + "\\" + strXMLFileName;
//ResultsForm.DisplayFile = strXMLFileName;
ResultsForm.ShowDialog();
}
Form 2
private frmNSTDBQC QCForm;
public frmResults(frmNSTDBQC qcForm)
{
InitializeComponent();
QCForm = qcForm;
}
Get same instance of Form1 where you add checkboxes in this way
Form2 is:
private Form1 form1;
public Form2(Form1 form)
{
form1 = form;
}
// now you can use form1 as object
and now show Form2 from Form1
var form2 = new Form(this); //pass instance
form2.ShowDialog();
If you have Both Forms open and you want them to interact, If you create first Form1 and then Form2, you can make Form2 able to see the changes in Form1 creating a CheckedListBox property inside Form2 and initializing it to the CheckedListBox object that stands inside Form1.
Pay attention that the reference is set after the CheckedListBox is created and its content initialized.
This however is a little bit a "raw" way to proceed. A better way to proceed would be to have a List of objects representing the data in the Form1
(E.g. List<Yourobject>)
as datasource of the CheckedListBox, bound to the properties in the listbox so that a Checked property in the data is set/reset by your listbox, and then share just this list of data between the two forms using a
List<YourObject>
collection that you set in a property of Form2 When opening it after you initialize it in the Form1.
Remember that the class YourObject must implement a PropertyChanged on the Checked property to inform of changes and also that if that is the case, it is better to use a BindingList not just a List collection object because the BindingList implements the events to inform the UI that its content has changed such as the ObservableCollection does for WPF.
HTH

c# getting the specific form to change specific value

How do I get specific opened form and change the value of specific property of the the form. I'm trying to cast Form to a specific form to change the values of that specific form.
I have multiple forms opened with dynamic name depending on the id
public UserChatFrm varUserChatFrm;
public void UserChatFrmOpener(string sendToEmpID)// function that will open multiple chat form depending n the senderid
{
if (Application.OpenForms["UserChatFrm" + sendToEmpID] == null)
{
varUserChatFrm = new UserChatFrm(sendToEmpID);
varUserChatFrm.Name = "UserChatFrm" + sendToEmpID;
varUserChatFrm.Tag = "UserChatFrm" + sendToEmpID;
varUserChatFrm.lblName.Text = sendToEmpID;
//varUserChatFrm.Text = sendToEmpID;
varUserChatFrm.MdiParent = Application.OpenForms["MainFrm"];
varUserChatFrm.Show();
}
varUserChatFrm.BringToFront();
}
Here are the opened forms
UserChatFrm UserChatFrm11 -> textbox1
UserChatFrm UserChatFrm12 -> textbox1 // I want to change the text of this
UserChatFrm UserChatFrm13 -> textbox1
UserlistFrm UserlistFrm ->listview
Here's my code to get that specific form
FormCollection fc = Application.OpenForms;
foreach (Form frm in fc)
{
if (frm.Name == "UserChatFrm" + rdr["emp_sys_id"].ToString())// this is queried in the database to naming specific form sample "UserChatFrm11"
{
UserChatFrm varUsrchat = frm; // not working error which has missing cast?
varUsrchat.textbox1.text = "sample"; // I want to change the value of specific
// or something like this
Application.OpenForms["UserChatFrm" + "12"].chatbox1.text = "sample"; //not working
}
}
Could you point out what am I missing?
I don't like the way you try to update the form, you can find a different solutions for this approach, my ideal way is create Interface and implement it for each form that you want update it, then cast the form to interface and Update the form:
public interface IFormUpdator<TModel> where TModel : class
{
void UpdateForm(TModel model)
}
Then implement this interface for each class:
public Form UserChatFrm : IFormUpdator<string>
{
public void UpdateForm(string model)
{
this.textbox1.text = model;
}
.....
}
then do the same for all other form which you want to update them
And you can update the form like this:
Application.OpenForms.OfType<IFormUpdator<string>>()
.ForEach(frm => frm.Update("Sample"));

I want a selected item in combobox on formlogin to be automatically changed in Main form

I have 2 forms:
first the loginform, which contains combobox1 that user will select
and then the Main form, which will be display the selected item in combobox1 on the label1 in loginform.
I tried :
label1.Text = "welcome, "+ (new formlogin()).comboBox1.selectedItems.ToString();
,but I've got an error with message:
Unhandled exception has occurred in your application.
There are so many ways to do this... but this is the simplest way that I can think of:
Add this property into your FormMain:
public string UserName { get; set; }
Then, in your FormMain's load event:
label1.Text = this.UserName;
Then, from your FormLogin when you show the MainForm:
FormMain form = new FormMain();
form.UserName = combobox1.selectedItems.ToString();
form.Show();
Okay, the error message in the screenshot said
object reference not set to an instance of an object.
That means that you're trying to use an unsubstantiated object
It is most likely is that your formlogin constructor doesn't actually instantiate combobox1.selectedItems, thus causing the error.
But what i think you might be trying to do is the following
label1.Text = "welcome, "+ this.comboBox1.selectedItems.ToString();
This is how I did it:
In your Main Form you first declare loginForm and show it:
formlogin logForm = new formlogin();
logForm.FormClosing += loginFormClosing;
logForm.ShowDialog();
Then declare a new Method
public void loginFormClosing()
{
//This method will be called when the loginform is closing
//declare a variable in your loginform class and call it here like:
label1.Text = "welcome, "+ logForm.selectedItem.ToString();
}
I'm sure there is a better and smarter way to do this. But this is how I do it.

Categories