Accessing Data Controls from a different form - c#

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.
}
}
}

Related

How can I reference my Bing Maps element from another form?

I've got a Bing Map element in UserControl1.xaml file:
<UserControl x:Class="MyMaps.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:m="clr-namespace:Microsoft.Maps.MapControl.WPF;assembly=Microsoft.Maps.MapControl.WPF">
<Grid>
<m:Map CredentialsProvider="Gr8GooglyMoogly" x:Name="myMap" />
</Grid>
</UserControl>
I can access it like so from Form1, on which it sits:
this.userControl11.myMap.Mode = new RoadMode();
...but when I try to access it from another form, none of these attempts work:
userControl11.myMap.Children.Add(pin); // does not exist in the current context
Form1.userControl11.myMap.Children.Add(pin); // inaccessible due to its protection level
UserControl1.myMap.Children.Add(pin); // object reference is required for the static field, ...
How can I get a handle on the UserControl from another form?
UPDATE
Using Reza's comment to change the Modifier property of the map from Private to Public, and utilizing the method shown at the link provided, the following works:
var frmMain = new Form1();
frmMain.userControl11.myMap.Children.Add(pin);
UPDATE 2
Reza's idea worked perfectly. This is how I tested it to verify:
In "Form 2" (mdlDlgFrm_AddNewLocation):
// to access map on main form (Form1)
private Form1 frmMain;
// second constructor so as to access map on main form (to add pushpins)
public mdlDlgFrm_AddNewLocation(Form1 f1)
{
InitializeComponent();
this.frmMain = f1;
// test
AddPushpin("blaJustATest");
}
private void AddPushpin(string fullAddress)
{
Pushpin pin = new Pushpin();
// "brute-forcing" the coordinates for this test
pin.Location = new Location(37.1481402218342, -119.644248783588); // Interesting location: out in the "boondocks" between Oakhurst and Auberry
this.frmMain.userControl11.myMap.Children.Add(pin);
}
...and "Form 2" being invoked from the main form (Form 1):
private void addLocationToolStripMenuItem_Click(object sender, EventArgs e)
{
mdlDlgFrm_AddNewLocation frmAddNewLocation = new mdlDlgFrm_AddNewLocation(this);
frmAddNewLocation.ShowDialog(this);
frmAddNewLocation.Dispose()
}
When you create a new form, you must send the current form as a parameter to the creator of the new form, where you can make changes to that instance using the instance you submitted.
In addition to all the options that I've already explained in the linked post and has been told in other posts, including the one that I mentioned in the comments, you can consider the following options here:
If you use ShowDialog to show Form2, you don't need a reference to Map or to Form1. Just return Pushpin from Form2 and use it.
OR Just pass the dependency, the Map to your second form. (No need to make the usercontrol public or pass the whole form1).
Example 1 - Return Pushpin
If you use ShowDialog to show Form2, you don't need a Map in Form2. Just create the Pushpin and return it back to Form1 and use it there.
In Form2, define a Pin property:
//using Microsoft.Maps.MapControl.WPF;
//...
public Pushpin Pin {get; set;}
In Form2, when you want to create the Pushpin, assign it to Pin property:
//...
this.Pin = new Pushpin(){Location = location};
this.DialogResult = DialogResult.OK;
Then in Form1 when you want to show Form2:
using(var f2 = new Form2())
{
if(f2.ShowDialog() == DialogResult.OK)
{
this.userControl11.myMap.Children.Add(f2.Pin);
}
}
Example 2 - Pass the Map
Just pass the dependency, the Map to your second form. You don't need to make the user control public or you don't need to pass the whole form1:
Change Form2 constructor to accept a Map:
//using Microsoft.Maps.MapControl.WPF;
//...
private Map map;
public Form2(Map map)
{
InitializeComponent();
this.map = map;
}
In Form1, when you want to show Form2:
var map = this.userControl11.myMap;
using(var f2 = new Form2(map))
f2.ShowDialog();
In Form2, when you want to use the map:
//...
var pin = new Pushpin(){Location = locatin};
map.Children.Add(pin);

Access data in datagridview from a class

I've read a lot of topics on this issue but I'm not finding an answer. I'm fairly new to this so please bear with me.
I'm trying to pass values from datagridview to a list. And then in a new class I want to make som methods accessing that list. Trouble is that when I pass the datagridview it returns it without content and values which means I can't do anything with it.
The code under ////TESTING//// works like I want. I create an instance of the specified list and it's counting the amount of rows properly, see screenshot.
public List<vertEl> getVertList = new List<vertEl>();
//Opens the file dialog and assigns file path to Textbox
OpenFileDialog browseButton = new OpenFileDialog();
private void browse_Click(object sender, EventArgs e)
{
browseButton.Filter = "Excel Files |*.xlsx;*.xls;*.xlsm;*.csv";
if (browseButton.ShowDialog() == DialogResult.OK)
{
//SOME CODE TO GET DATA FROM EXCEL AND SOME METHODS TO CALCULATE
//VALUES TO PASS TO THE TAB VERTIKALELEMENTER TAB IN MY DATAGRIDVIEW
//VERTIKALELEMENTER IS vertElementerDgv IN MY CODE
////TESTING////
GetVertElementasList TEST = new GetVertElementasList();
getVertList = TEST.vertList(vertElementerDgv);
MessageBox.Show(getVertList.Count.ToString());
}
else return;
}
I now want to do this in a seperate class and call a method from that class to do the same but when I try that with code underneath I do not get the same count as when I have the code in form1 (public partial class BridgeGeometry). It return count of 0. The method foo() is assigned to the button 1 in the form.
class GetKoord
{
public GetVertElementasList getList = new GetVertElementasList();
BridgGeometry obj = new BridgGeometry();
public void foo()
{
var TEST = getList.vertList(obj.vertElementerDgv);
//var TEST = obj.getVertList;
MessageBox.Show(TEST.Count.ToString());
}
}
I also tried to get the values directly from the datagridview but there's nothing in it when I access it from a class which is not the form1/BridgeGeometry class.
Form - screenshot
You could run a loop and store the information with selected rows into a public var with something like this:
string itemOne = dataGridView1.SelectedRows[0].Cells[1].Value + string.Empty;
string itemTwo= dataGridView1.SelectedRows[0].Cells[2].Value + string.Empty;
string itemThree = dgMasterGridBun.SelectedRows[0].Cells[3].Value + string.Empty;
Variables
public var varItemOne = itemOne;
public var varItemTwo = itemTwo;
public var varItemThree = itemThree;
Based on the link I managed to get this working. Probably not the best solution, but a working one. I tried to wrap my head around databinding, listbinding etc. but since the class with the input values are a messy one I gave that up for now. The datagriview input values are a little from lists and some from other datagridview.
MSDN-forum: Accessing Form1 controls from a different class
Explanations are given in the link so I'll just provide how I did it in my program.
If my GetKoord class are like this:
public class GetKoord
{
private BridgGeometry bridgeGeometry;
public GetKoord(BridgGeometry form1)
{
bridgeGeometry = form1;
}
public List<vertElementerParam> getListvertElementer(List<vertElementerParam> theList)
{
//var vertElementerDgv = bridgeGeometry.vertElementerDgv;
GetVertElementasList getVertElementasList = new GetVertElementasList();
List<vertElementerParam> MyDgvListList = new List<vertElementerParam>();
MyDgvListList = getVertElementasList.vertList(bridgeGeometry.vertElementerDgv);
//MessageBox.Show(MyDgvListList.Count.ToString());
theList = MyDgvListList;
return theList;
}
}
then I can get the list in Button1_Click like this, check the screenshot in the first post:
public List<vertElementerParam> getVertList = new List<vertElementerParam>();
private void button1_Click(object sender, EventArgs e)
{
GetKoord getKoord = new GetKoord(this);
List<vertElementerParam> testList = new List<vertElementerParam>();
testList = getKoord.getListvertElementer(getVertList);
MessageBox.Show(testList.Count.ToString());
}

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"));

How to put data from one form into a listbox in another

Okay so I'm adapting a C# program to an asp program and I have a main form which contains a list box and another which adds new information to the list box. I can fill in the 2nd form and hold values in Application["getData"]; but when I go to the other page I need to run the following code.
public void AddGig()
{
AddGigForm frm = new AddGigForm();
if (Application["getData"] != null)
{
Application["saveData"] = Application["getData"];
gigList.addGig(frm.GetData());
UpdateListbox();
}
I run into problems at gigList.addGig as it goes back to the method GetData() on the 2nd form. I just have no idea what else to use.
GetData method:
public GigOpportunity GetData()
{
Application["GetData"] = new GigOpportunity
(txtId.Text, gigDate.SelectedDate, txtVenue.Text, txtGenre.Text,
Convert.ToDouble(txtCost.Text), Convert.ToInt32(txtCapacity.Text), chkHeadliner.Checked, txtMainAct.Text, chkEngineer.Checked);
return new GigOpportunity(txtId.Text, gigDate.SelectedDate, txtVenue.Text, txtGenre.Text, Convert.ToDouble(txtCost.Text), Convert.ToInt32(txtCapacity.Text), chkHeadliner.Checked, txtMainAct.Text, chkEngineer.Checked);
}
addGig method:
public void addGig(GigOpportunity gigOpportunity)
{
//Make sure a gig with this id does not already exist
foreach (GigOpportunity g in gigList)
{
if (g.GigId == gigOpportunity.GigId)
{
throw new DuplicateIdException();
}
}
gigList.Add(gigOpportunity);
}
I understand now your problem. You musn't think like in windows form. You declared those method inside other form. When you call it by assigning a new Form object you will not get the value inside as they have been disposed after you change the page.
So in your case:
if (Application["getData"] != null)
{
Application["saveData"] = Application["getData"];
gigList.addGig((GigOpportunity)Application["getData"]);
UpdateListbox();
}
But I will suggest you to use Session object instead of Application object.
You can read more about it here
So you have to do like this:
if (Session["getData"] != null)
{
Session["saveData"] = Session["getData"];
gigList.addGig((GigOpportunity)Session["getData"]);
UpdateListbox();
}
You don't need to create the second form object AddGigForm and you must be sure to call your methodGetData in the form where is it declared to assign your Session.

how to avoid rebinding grid each time the control is initialized?

I've created a custom user control with a grid. I'd like to bind this grid once, and use it over and over again in my app. If I put the binding within the control, the data is retrieved as many times as I use the control. How do I bind it only once??
public ClientLookUp()
{
InitializeComponent();
vw_clientsTableAdapter.Fill(dsclientlkup.vw_clients); //This occurs as many times as I have the user control, instead of just once.
}
Well anything you put in the constructor will be executed every time you construct the object!
What about providing an Initialize method that you can call whenever you need to reload the data??
If you want to load the data only once, then load it either into a static variable or a separate class that is referenced by the control.
If you really want to use the same single grid in your control over and over, you could create a single, static grid, and have your ClientLookUp constructor add it to the right place—Panel, or whatever—whenever a new one is created.
Before you go do this road however, ask yourself if this is really what you want to do. Having the same identical grid existing in many places may cause you problems down the road. If you want to support in-grid editing, you'll find that changing one value changes the identical value in all your other grids..
EDIT
I tried getting the below code to work, but I'm not sure this approach will be possible. It seems as though the minute you try to attach the same UI element into more than one place, it gets moved out of the last place you put it; it doesn't look like you can have the same grid being in more than one place at once. This makes sense when you think about it.
Here's the code I tried. Maybe it will be of some use to you.
public UserControl1()
{
InitializeComponent();
this.Controls.Add(myStaticGridView);
myStaticGridView.Dock = DockStyle.Fill;
}
static DataGridView _staticGrid;
public DataGridView myStaticGridView
{
get
{
if (_staticGrid != null)
return _staticGrid;
_staticGrid = new DataGridView();
_staticGrid.Columns.Add("A", "A");
_staticGrid.Columns.Add("B", "B");
_staticGrid.Columns.Add("C", "C");
_staticGrid.Columns[0].DataPropertyName = "A";
_staticGrid.Columns[1].DataPropertyName = "B";
_staticGrid.Columns[2].DataPropertyName = "C";
_staticGrid.DataSource = new[] {
new { A = "someA", B = "someB", C = "someC"},
new { A = "someA", B = "someB", C = "someC"},
new { A = "someA", B = "someB", C = "someC"},
new { A = "someA", B = "someB", C = "someC"},
};
return _staticGrid;
}
}
And then loading the control like this:
private void button1_Click(object sender, EventArgs e)
{
flowLayoutPanel1.Controls.Add(new UserControl1());
}

Categories