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"));
Related
When I search this question, all of the answers I've seen only talk about handling an object within the same class but I need to handle the same data between classes.
I'm building an outlook addin which uses three classes to make up the key components of my programme:
ThisAddin - the default class created with the MS VS template, I'm using this class to store all of my methods, enums, data stores etc..
Ribbon - my outlook Ribbon containing a button to initiate a new enquiry form. Within the button_click is also a code to save relevant attachments from a selected email to a specified filepath.
NewEntry - a winform dialogue initiated when the ribbon button is clicked, used to create new enquiries.
I also have a class called NewSearchQuery which I was hoping to use as a datastore for all the relevant aspects of a new enquiry.
current logic goes like this - user presses button in the ribbon, a new object (referenced as Temp) is called and known data for some parameters are filled. Winform is opened and user fills in some more required data. On form submit, that data is added to the object metadata, a reference number is generated from a database, a file path is created using the reference number and all this is again added to the object metadata. Winform dialog closes and the ribbon saves the selected email attachments to the specified filepath stored within the object. Now all the object metadata can be sent to the enquiry database as a new enquiry.
Here's the code:
public enum ContractType
{
Searches, //there are other values in my code but they don't need to feature here
}
public class NewSearchQuery
{
public string Name, Location, SearchType, Path;
public int RefNum;
public bool Paid;
public ContractType Contract;
}
public partial class Ribbon
{
private void button1_Click(object sender, RibbonControlEventArgs e)
{
NewSearchQuery Temp = new NewSearchQuery();
Temp.Contract = ContractType.Searches;
var NewEntry = new NewEntry(Convert.ToString(Temp.Contract));
NewEntry.ShowDialog();
//wait until the NewEntry Dialogue and associated methods close and then run the below save attachments method:
var m = e.Control.Context as Inspector;
var mailitem = m.CurrentItem as MailItem;
mailitem.SaveAs(Temp.Path + #"\Initial_Contact.msg");
if (mailitem != null)
{
if (mailitem.Attachments.Count > 0)
{
foreach (Attachment item in mailitem.Attachments)
{
string[] extensionsArray = { ".jpg", ".jpeg", ".gif", ".png", ".tiff", ".tif", ".eps", ".bmp", ".vcf" };
if (!extensionsArray.Any(item.FileName.Contains))
{
item.SaveAsFile(Path.Combine(Temp.Path, item.FileName));
}
}
}
else
{
MessageBox.Show($"Operation Complete. Enquiry number {Temp.RefNum}. This email doesn't have any attachments.");
}
}
MessageBox.Show($"Operation Complete, Enquiry number {Temp.RefNum}.");
}
}
public partial class NewEntry : Form
{
public NewEntry(string ContractType)
{
InitializeComponent();
}
private void Create_Click(object sender, EventArgs e)
{
//here are the variables I would like to tie into the Temp object created in Ribbon
Temp.Name = Convert.ToString(Companies.SelectedItem);
Temp.Location = Convert.ToString(SearchLocation.Text);
Temp.SearchType = Convert.ToString(Search.SelectedItem);
Temp.Paid = Paid.Checked;
if (Temp.Name == "" || Location == "" || SearchType == "")
{
MessageBox.Show("Please ensure you have filled in all the required fields (*) before proceeding", "ERROR: insufficient info");
}
else
{
Temp.RefNum = ThisAddIn.FindIdNum();
Temp.Path = ThisAddIn.CreateFilePath(Temp.RefNum);
MessageBox.Show(Convert.ToString(d));
this.Close();
}
}
}
How can I reference the same object from both the Ribbon and NewEntry classes to keep all my required data centralised?
It looks like you don't need to actually share and you only want NewEntry to give you a NewSearchQuery when it completes.
That is pretty easy just add a method on NewEntry like this:
public NewSearchQuery GetEntry()
{
// make a new NewSearchQuery
var q = new NewSearchQuery();
// set its values from the form eg
q.Name = Convert.ToString(Companies.SelectedItem);
return q;
}
Then in the ribbon just do this after the ShowDialog:
var q = NewEntry.GetEntry();
So the idea is that the NewSearchQuery is always created by the form.
If you want a 2 way thing, create the NewSearchQuery first, then pass to the form using a similar method that initializes the form from the values.
I have several classes in my program and I'm using Windows Form to create the objects from the different classes and list them in different listboxes.
Right now I have a form with all the listboxes (Form 1) and another form (CreerVoiture) where i put all the info to create my selected object.
An example is when i click on the button "Voiture!" my second form opens, when I add all the info and push on "Ajouter" it adds the object to the listbox selected.
Code from Form1:
private void button1_Click(object sender, EventArgs e)
{
CreerVoiture creervoiture = new CreerVoiture();
if (creervoiture.ShowDialog(this) == DialogResult.OK)
{
// Read the contents of form2's TextBox.
Voiture voiture = new Voiture(creervoiture.GetMarque(), creervoiture.GetPrix(), creervoiture.GetConsommation(), creervoiture.GetReservoir());
this.list_voiture.Items.Add(voiture);
this.list_voiture.DataSource = null;
}
creervoiture.Dispose();
}
What I would like to know is how I can access a parameter I added in my second form once I added it to the listbox.
I was thinking to use something like:
list_voiture.SelectedItem.Prix
Prix is a getter from my class Voiture
public double Prix
{
get { return this.prix; }
set { this.prix = value; }
}
But that doesn't seem to be possible. Is this possible and if so, how?
Thanks in advance,
Jeremy
If the type of object is Voiture then you can cast the object to that type:
Voiture voiture = (Voiture)list_voiture.SelectedItem;
double prix = voiture.Prix;
Or in one line:
double prix = ((Voiture)list_voiture.SelectedItem).Prix;
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
i have two forms, form A and form B, to access form B from from A i pass form B in the constructor of form A, that way i am able to access a gridview.
Suggestions were made directing me towards exposing my gridview in a public property and passing it to the other form i want to access it from.
This is my understanding of what was suggested to me:
public RadGridView Grid
{
get { return GridViewDisplay; }
}
then i pass this property to my second form:
Form1 f1 = new form1();
Form2 f2 = new form2(f1.Grid);
This is my issue here:
public void DockAllWindows()
{
SideBar sb = new SideBar();
Summary sm = new Summary();
SalesPoint sp = new SalesPoint(sb, sm); // This is where my issue is, Point A
StartPage start = new StartPage();
radDock.DockControl(sp, (DockPosition.Fill), DockType.Document);
radDock.DockControl(start, (DockPosition.Fill), DockType.Document);
radDock.DockControl(sm, (DockPosition.Right), DockType.ToolWindow);
}
At Point A i am passing an object instance of my summary form to my SalePoint form.
therefore i cannot execute the following code as it would generate an error:
Summary sm = new Summary(sp.Grid); // Error right here
SalesPoint sp = new SalesPoint(sb, sm);
I would like some help getting around the above error.
You need to set the Summary.Grid property after you've created your SalesPoint class.
Summary sm = new Summary();
SalesPoint sp = new SalesPoint(sb, sm);
sm.Grid = sp.Grid.
To be clear you need a public grid property on your SalesPoint class and one on your Summary class. And make you implement the set on the property of the Summary class so you know when someone else changes it.
public RadGridView Grid
{
get { return grid; }
set
{
if (grid != value)
{
grid = value;
// Add any special processing that summary needs to do to pull data from the SalesPoint Grid property.
}
}
}
I have created a custom message box with a textbox for input which appears under a certain condition in form1. I want form1 to hold the value of the textbox if the submit btn is clicked. I am not getting the desired result.
This is similar to this however I don't want the processing to happen in the message box because the process requires so many variables that I would have to transfer to the messsagebox.
Form condition
}
else //NOT ALL APPROVE
{
string BtnClicked = DenyEmpRequest.ShowBox(AllDenied, EmpRequestID);
if (BtnClicked == "1") //SUBMIT BTN WAS CLICKED
{
DenyEmpRequest emp = new DenyEmpRequest();
string reason = emp.Reason_Txt.Text;
}
I know that it is because I am creating a new instance of the form that I used in the messagebox when I said "DenyEmpRequest emp = new DenyEmpRequest();". I don't know any other way to access the textbox in the messagebox.
Messagebox code
public static string ShowBox(string DenyEmp, string RequestID)
{
newMessageBox = new DenyEmpRequest();
newMessageBox.EmpToDeny_lbl.Text = DenyEmp;
EmpRequestID = RequestID;
newMessageBox.ShowDialog();
return Button_id;
}
private void SubmitBtn_Click(object sender, EventArgs e)
{
if (Reason_Txt.Text == string.Empty)
{
NoReason_Lbl.Visible = true;
}
else
{
Button_id = "1";
newMessageBox.Dispose();
}
Looks like you're overcomplicating it. If you are just trying to retrieve a string from a custom MessageBox, just make a form with an OK/Cancel button and a text box. Make a public string property that wraps around the value of the text box's "Text" property. And make the form set it's DialogResult to DialogResult.OK if the OK button is clicked, DialogResult.Cancel if the cancel button is clicked.
Then you can call this form with code shown below:
using (CustomMessageBox myMessageBox = new CustomMessageBox())
{
myMessageBox.Text = "Initial text"; // optionally set the initial value of the text box
if (myMessageBox.ShowDialog(this) == DialogResult.OK)
{
someVariable = myMessageBox.Text;
}
}
This is the format you should be using.
EDIT:
In reference to your comment, if you have a form with a text box on it, just write the property like this:
public class CustomMessageBox : Form
{
public string Text
{
get
{
return textBox.Text;
}
set
{
textBox.Text = value;
}
}
}