C# Communication between parent form and child form - c#

My project has two classes. The first class has information about continents and it contains also a list of objects of countries (another class).
I also declared a list of continents that contains all the continents.
I've succeeded in filling the list from a file, and succeeded to show them in a DataGridView in the same form. But the problem is that I didn't find a way to show them in a child form that contains a DataGridView.
So, how can I transfer the list of continents to the child form so that I can be able to show them in it?
I tried serialiization and deserialization, but it didn't work, I just see the name of members of continent class and nothing else.
Here are the two class and code of toolstrip that show the child form:
// first class of continent
namespace WindowsFormsApplication1
{
[Serializable]
class continent
{
//champs
private string nomc;
public string Nomc
{
get { return this.nomc; }
}
private string sup;//SUP
public string Superficie
{
get { return this.sup; }
set { this.sup = value; }
}
private string pop;//POP
public string Population
{
get { return this.pop; }
set { this.pop = value; }
}
private string dens;//DENS :
public string Densité
{
get { return this.dens; }
set { this.dens = value; }
}
private string nbp;//NBP : 54 :
public string nombre_de_Pays
{
get { return this.nbp; }
set { this.nbp = value; }
}
private string fus;//FUS )
public string Fuseaux_horaires
{
get { return this.fus; }
set { this.fus = value; }
}
private string pnb;//PNB
public string PNB_habitant
{
get { return this.pnb; }
set { this.pnb = value; }
}
//constructeur
public continent(string nom)
{
this.nomc = nom;
}
public continent()
{
// TODO: Complete member initialization
}
//list of countries of that continent
public List<country> listep = new List<country>();
}
// class of countries
namespace WindowsFormsApplication1
{
[Serializable]
class country
{
//champs
private string nom_p;
public string Nom_pays
{
get { return this.nom_p; }
set { this.nom_p = value; }
}
private string cap;//PCAP
public string Capitale
{
get { return this.cap; }
set { this.cap = value; }
}
private string sup;// PSUP
public string Superficie
{
get { return this.sup; }
set { this.sup = value; }
}
private string reg;// REG
public string Régime_politique
{
get { return this.reg; }
set { this.reg = value; }
}
private string dev;//PDEV nationale
public string Devise
{
get { return this.dev; }
set { this.dev = value; }
}
private string hym;// PHYM
public string Hymne
{
get { return this.hym; }
set { this.hym = value; }
}
private string lg;// PLG
public string Langue
{
get { return this.lg; }
set { this.lg = value; }
}
private string mo;// PMO
public string Monnaie
{
get { return this.mo; }
set { this.mo = value; }
}
private string de;
public string PDE
{
get { return this.de; }
set { this.de = value; }
}
//constructeur
public country (string nom)
{
this.nom_p = nom;
}
}
}
and the code in the form is
//liste of contnents
List<continent> listec = new List<continent>();
// i filled it from a file
//here the code of toolstrip that open the childform
private void listeContinentToolStripMenuItem_Click(object sender, EventArgs e)
{
listecont flc = new listecont();
flc.ShowDialog();
flc.MdiParent = this;
}

In your child form, add an overload to the Form constructor that takes a Form as an argument. Then when you create your child form, you can pass in an instance of your current (parent) form like, listecont flc = new listecont(this); where this is a reference of your parent form. Now your child form can make calls to parentForm.Textbox.Text = "blablabal" or what ever object you want to interact with.

Why not just add a constructor to the listecont class that takes a List<continent>? Then, the child form will have the data when it's constructed.

in your MDI child add a method:
public void SetContinentData(List<continent> list)
{
// add your DataSource to the grid
// f.e.:
dataGridView.DataSource = list;
}
and in your Toolstrip handler:
private void listeContinentToolStripMenuItem_Click(object sender, EventArgs e)
{
listecont flc = new listecont();
flc.SetContinentData(listec);
flc.ShowDialog();
flc.MdiParent = this;
}

Related

PropertyGrid with same childs and different nodes

I want my custom PropertyGrid with student1 and student2 as nodes with "Name,Section,Percentage,School" as childs for both nodes.
I tried like this :
class StudentClass
{
private string name;
private string section;
private string percentage;
private string school;
[CategoryAttribute("Student1")]
public string School
{
get { return school; }
set { school = value; }
}
[CategoryAttribute("Student1")]
public string Percentage
{
get { return percentage; }
set { percentage = value; }
}
[CategoryAttribute("Student1")]
public string Section
{
get { return section; }
set { section = value; }
}
[CategoryAttribute("Student1")]
public string Name
{
get { return name; }
set { name = value; }
}
private string name1;
[CategoryAttribute("Student2")]
public string Name1
{
get { return name1; }
set { name1 = value; }
}
private string section1;
[CategoryAttribute("Student2")]
public string Section1
{
get { return section1; }
set { section1 = value; }
}
private string percentage1;
[CategoryAttribute("Student2")]
public string Percentage1
{
get { return percentage1; }
set { percentage1 = value; }
}
private string school1;
[CategoryAttribute("Student2")]
public string School1
{
get { return school1; }
set { school1 = value; }
}
}
public Form1()
{
InitializeComponent();
StudentClass sc = new StudentClass();
propertyGrid1.SelectedObject = sc1;
}
The Output is as shown below :
Now in the above picture for Student2 instead of "Name1,Section1,Percentage1,School1" I want to display same as student1.
But I didn't get the required output. So Kindly help me out of this.
I am using C# Winforms in VS2010
And Suggest me how to deny columns resizing i.e., I should not allow user to resize the columns.
You can use the DisplayName attribute:
private string name1;
[CategoryAttribute("Student2"), DisplayName("Name")]
public string Name1
{
get { return name1; }
set { name1 = value; }
}
But note that if the user puts the property grid into A-Z mode, they'll both end up next to each other with no real way to tell them apart. You may find there's a more appropriate way to represent your data.

Custom Collection/List To Store Custom Objects

I have a customer object class:
public class customerObject
{
private string _address1;
private string _address2;
private string _address3;
private string _category;
private string _country;
private string _county;
private string _custcode;
private string _fullname;
private string _int_rep_hou;
private string _int_rep_key;
private double _lat;
private double _lng;
private string _postcode;
private string _rep_code;
private string _telephone;
public customerObject()
{
}
public string Address1
{
get { return _address1; }
set { _address1 = value; }
}
public string Address2
{
get
{
return _address2;
}
set { _address2 = value; }
}
public string Address3 { get { return _address3; } set { _address3 = value; } }
public string Category
{
get { return _category; }
set { _category = value; }
}
public string Country { get { return _country; } set { _country = value; } }
public string County { get { return _county; } set { _county = value; } }
public string Custcode
{
get { return _custcode; }
set { _custcode = value; }
}
public string Fullname
{
get { return _fullname; }
set { _fullname = value; }
}
public string Int_rep_hou
{
get { return _int_rep_hou; }
set { _int_rep_hou = value; }
}
public string Int_rep_key
{
get { return _int_rep_key; }
set { _int_rep_key = value; }
}
public double Lat { get { return _lat; } set { _lat = value; } }
public double Lng { get { return _lng; } set { _lng = value; } }
public string Postcode { get { return _postcode; } set { _postcode = value; } }
public string Rep_code
{
get { return _rep_code; }
set { Rep_code = value; }
}
public string Telephone { get { return _telephone; } set { _telephone = value; }
}
}
I have a CustomCollections class
public class CustomerCollection
{
public List<customerObject> Customers { get; set; }
}
My method that loops through dt rows and converts to a customer object
public List<Valueobjects.CustomerCollection> dolist(DataTable temptablename)
{
//Create Collection Object
Valueobjects.CustomerCollection Collection = new Valueobjects.CustomerCollection();
foreach (DataRow row in temptablename.Rows)
{
//Create Customer Object
Valueobjects.customerObject Customer = new Valueobjects.customerObject();
//set values of customer object
Customer.Rep_code = "";
Customer.Int_rep_key = "";
Customer.Int_rep_hou = "";
Customer.Fullname = row["Fullname"].ToString().Trim();
Customer.Custcode = row["Custcode"].ToString().Trim();
Customer.Category = row["Category"].ToString().Trim();
Customer.Address1 = row["Address1"].ToString().Trim();
Customer.Address2 = row["Address2"].ToString().Trim();
Customer.Address3 = row["Address3"].ToString().Trim();
Customer.Postcode = row["Postcode"].ToString().Trim();
Customer.Country = row["Country"].ToString().Trim();
Customer.Telephone = row["Telephone"].ToString().Trim();
Customer.Lat = Convert.ToDouble(row["Lat"]);
Customer.Lng = Convert.ToDouble(row["Lng"]);
Customer.County = row["County"].ToString().Trim();
//add to the collection (list)
Collection.Customers.Add(Customer);
}
temptablename = null;
return Collection;
}
However when I create a new Customer object and a new CustomerCollection object I am getting an error when adding the customer to the collection list.
Error:
Error 32 Cannot implicitly convert type
'Classes.Valueobjects.CustomerCollection' to
'System.Collections.Generic.List'
Your method is returning a List<CustomerCollection>:
public List<Valueobjects.CustomerCollection> dolist(DataTable temptablename)
{
//...
}
But the code is trying to return a CustomerCollection:
return Collection;
Just as the error says, these two types are different.
If a CustomerCollection is already a collection of customers, then semantically what is a List<Valueobjects.CustomerCollection>? A collection of collections? It seems like you're over-pluralizing your objects :)
There are two approaches here. Either return a CustomerCollection from the method:
public CustomerCollection dolist(DataTable temptablename)
{
//...
}
Or use a List<Customer> if you want to use generic lists as your collection containers:
public List<Customer> dolist(DataTable temptablename)
{
//...
var Collection = new List<Customer>();
//...
Collection.Add(Customer);
//...
return Collection;
}
Side note: You may want to stick to C# conventions for variable naming. As you can see from the code highlighting here on Stack Overflow, your variable names can easily be mistaken for classes/types, which can cause confusion when supporting the code.
Return a CustomerCollection instead of a List<Valueobjects.CustomerCollection>:
public Valueobjects.CustomerCollection Dolist(DataTable temptablename)
{
// ...
Your object has a list, it is not a list.
MSDN: Inheritance

Inserting a list into a listbox in C#

I have made a list and the data is added into the list by the user using textboxes and comboboxes, I am now trying to enter this list of data into a listbox but everytime I try to add the data I get the output as the class name e.g WindowApplicaion.Journey or it comes out as System.Collections.Generic.List`1[WindowApplication.Journey], i'm not sure if this is due to me placing the conversion code in the wrong place or i'm just doing it all wrong, here is my code for both cases:
private void ShowAllToursbttn_Click(object sender, RoutedEventArgs e)
{
foreach (Tour t in company.tours)
{
string converter = company.tours.ToString();
ToursListBox.Items.Add(converter);
}
}
or
private void ShowAllToursbttn_Click(object sender, RoutedEventArgs e)
{
foreach (Tour t in company.tours)
{
string ConvertedList = string.Join(" ", company.tours);
TourListBox.Items.Add(ConvertedList);
}
}
Where tours is my list I created in my company class and t is each instance in the list, any advice would be great, thank you!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowApplication
{
class Tour
{
private string custFirstname;
private string custSurname;
private string custAddress;
private string pickupArea;
private string pickupDateandTime;
private string pickupDescription;
private string destinationArea;
private string destinationDescription;
//Creating getters and setters for each attribute
#region getters/setters
public string firstname
{
get { return custFirstname; }
set { custFirstname = value; }
}
public string surname
{
get { return custSurname; }
set { custSurname = value; }
}
public string address
{
get { return custAddress; }
set { custAddress = value; }
}
public string pickuparea
{
get { return pickupArea; }
set { pickupArea = value; }
}
public string pickupdateandtime
{
get { return pickupDateandTime; }
set { pickupDateandTime = value; }
}
public string pickupescription
{
get { return pickupDescription; }
set { pickupDescription = value; }
}
public string destinationarea
{
get { return destinationArea; }
set { destinationArea = value; }
}
public string destinationdescription
{
get { return destinationDescription; }
set { destinationDescription = value; }
}
}
}
That is my Tour class.
private void AddThisTourbttn_Click(object sender, RoutedEventArgs e)
{
Tour t = new Tour();
t.firstname = CustomerFirstnameTxt.Text;
t.surname = CustomerSurnameTxt1.Text;
t.address = CustomerAddressTxt.Text;
t.pickupdateandtime = TourDateTimeTxt.Text;
t.pickuparea = TourPickupArea.Text;
t.pickupescription = TourPickupDescriptionTxt.Text;
t.destinationarea = TourDestinationArea.Text;
t.destinationdescription = TourDestinationDescriptionTxt.Text;
company.addTour(t);
}
and on my MainWindow I have assigned each textbox to its appropriate get/set.
Your program displaying class name in listbox because you use default object's toString() method in ShowAllToursbttn_Click, which will output class name. Try to override ToString() method in Tour class, to output string with your desired format for example:
public override string ToString()
{
return String.Format("Firstname: {0}; Surname: {1}", firstname, surname);
}
And change ShowAllToursbttn_Click logic to:
private void ShowAllToursbttn_Click(object sender, RoutedEventArgs e)
{
foreach (Tour t in company.tours)
{
TourListBox.Items.Add(t.ToString());
}
}

Nested object lists, last list not accessible?

In the code below I try to add the AttributeValueInfoEntity to the AttributeValueExportList, however it is not showing up as a property of the ArticleAttributeExportLarge object at the place where I put //largeExportList.AttributeExportList in the code.
Am I doing something wrong, or am I missing a important nesting rule in C#?
public partial class Export_Articles_Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
ArticleInfoEntity[] articleInfoList = ArticleInfoFactory.Instance.ListInfo(244);
List<ArticleExportLarge> list = new List<ArticleExportLarge>();
foreach (ArticleInfoEntity aie in articleInfoList)
{
ArticleExportLarge largeExportList = new ArticleExportLarge(aie);
largeExportList.AttributeExportList = new List<ArticleAttributeExportLarge>();
List<AttributeInfoEntity> attributeInfoList = AttributeInfoFactory.Instance.ListByArticle(aie.ArticleId);
foreach (AttributeInfoEntity attributeInfo in attributeInfoList)
{
largeExportList.AttributeExportList.Add(new ArticleAttributeExportLarge(attributeInfo));
List<AttributeValueInfoEntity> ArticleValueInfoList = AttributeValueInfoFactory.Instance.ListByArticleAndAttribute(aie.ArticleId, attributeInfo.AttributeId);
foreach (AttributeValueInfoEntity avie in ArticleValueInfoList)
{
//largeExportList.AttributeExportList
}
}
list.Add(largeExportList);
}
}
}
public class ArticleExportLarge
{
private ArticleInfoEntity articleInfo;
private List<ArticleAttributeExportLarge> attributeExportList;
public ArticleExportLarge(ArticleInfoEntity articleInfo)
{
this.articleInfo = articleInfo;
}
[XmlElement(ElementName = "attributeList")]
public List<ArticleAttributeExportLarge> AttributeExportList
{
get { return attributeExportList; }
set { attributeExportList = value; }
}
}
public class ArticleAttributeExportLarge
{
private AttributeInfoEntity attributeInfo;
private List<ArticleAttributeValueExportLarge> attributeValueExportList;
public ArticleAttributeExportLarge(AttributeInfoEntity attributeInfo)
{
this.attributeInfo = attributeInfo;
}
[XmlElement(ElementName = "attributeValueList")]
public List<ArticleAttributeValueExportLarge> AttributeValueExportList
{
get { return attributeValueExportList; }
set { attributeValueExportList = value; }
}
}
public class ArticleAttributeValueExportLarge
{
private AttributeValueInfoEntity attributeValueExportEntity;
public AttributeValueInfoEntity AttributeValueExportEntity
{
get { return attributeValueExportEntity; }
set { this.attributeValueExportEntity = value; }
}
}
I found my error. I need to iterate through the secondary list largeExportList.AttributeExportList if I want to access the objects in that list.

C# - Marshall by value problem!

Here is the thing, I have a problem creating a new object using the remote mechanism "marshal by value".
Here is my class:
[Serializable]
internal class Empleado_MBV
{
public Empleado_MBV()
{
Id = 123456789;
Nombres = "NotEntry";
Apellidos = "NotEntry";
FechaNacimiento = DateTime.MinValue;
Direccion = "NotEntry";
Metapreferencias = "NotEntry";
}
private List<Multas> _multas;
internal List<Multas> Multas
{
get { return _multas; }
set { _multas = value; }
}
private int _id;
public int Id
{
get { return _id; }
set { _id = value; }
}
private string _nombres;
public string Nombres
{
get { return _nombres; }
set { _nombres = value; }
}
private string _apellidos;
public string Apellidos
{
get { return _apellidos; }
set { _apellidos = value; }
}
private DateTime _FecNac;
public DateTime FechaNacimiento
{
get { return _FecNac; }
set { _FecNac = value; }
}
private string _direccion;
public string Direccion
{
get { return _direccion; }
set { _direccion = value; }
}
private string _metapreferencias;
public string Metapreferencias
{
get { return _metapreferencias; }
set { _metapreferencias = value; }
}
public string _AppDomainHost
{
get { return AppDomain.CurrentDomain.FriendlyName.ToString(); }
}
}
But when I try to create an object in another "appdomain", the property "_AppDomainHost" of "Empleado" does not show the "appdomain" I had created, but show the "appdomain" by default. Some ideas?
AppDomain ad1 = AppDomain.CreateDomain("NewAppDomain");
//Crear new object in my new AD.
Empleado_MBV mbv_emp = (Empleado_MBV)ad1.CreateInstanceFromAndUnwrap("DEMO_MBV_MBR.exe", "DEMO_MBV_MBR.Empleado_MBV");
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName.ToString());
Console.WriteLine("MBV : {0}",mbv_emp._AppDomainHost.ToString());
Console.ReadLine();
Result:
DEMO_MBV_MBR.vshost.exe
MBV : DEMO_MBV_MBR.vshost.exe
The result that I want:
DEMO_MBV_MBR.vshost.exe
MBV : NewAppDomain
You need to store AppDomain in Empleado_MBV's constructor.
What you are doing right now is displaying current AppDomain using its Current static property. It will return the AppDomain where current code is being executed.
Example:
private string _appDomainHost;
public string _AppDomainHost
{
get { return _appDomainHost; }
}
and in constructor:
_appDomainHost = AppDomain.CurrentDomain.FriendlyName.ToString();

Categories