I am trying to interact the DataGridView, located in Form1 (frPlanDeLucru), by a button in Form2. The reason for this is to create a separate search window. I keep getting Error CS0122, frPlanDeLucru.dataGridView1' is inaccessible due to its protection level.
Please help.
The Code in Form 1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.OleDb;
namespace Plan_de_lucru
{
[Serializable()]
public partial class frPlanDeLucru : Form
{
public frPlanDeLucru()
{
InitializeComponent();
}
public void TextBox1_TextChanged(object sender, EventArgs e)
{
}
public void ctrlLoad_Click(object sender, EventArgs e)
{
string constr = "Provider = MicroSoft.Jet.OLEDB.4.0; Data Source=" + TextBox1.Text + "; Extended Properties =\"Excel 8.0; HDR=Yes;\";";
OleDbConnection con = new OleDbConnection(constr);
OleDbDataAdapter sda = new OleDbDataAdapter("Select * From [" + textBox2.Text + "$]", con);
DataTable dt = new DataTable();
sda.Fill(dt);
dataGridView1.DataSource = dt;
new Form2().Show();
this.Show();
}
}
}
The code in Form2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Plan_de_lucru
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
public void search_button_Click(object sender, EventArgs e)
{
String str = "select * from searchBox where ( Name like '%' + #search + '%')";
BindingSource bs = new BindingSource();
bs.DataSource = frPlanDeLucru.dataGridView1.DataSource; //<- Here is the problem, do not know the fix
}
}
}
In Form2:
public DataGridView Dgv { get; set; }
In Form1:
Form2 f = new Form2();
f.Dgv = dt; //Add this to the ctrlLoad_Click
In Form2 access its own Dgv propety.
You could add a reference to form a when creating form b and expose a public method / property in that "formA" that returns the datasource you wish. An example in which this is used:
public class FormA
{
public FormA()
{
}
public object GetDataSource()
{
return datagrid1.DataSource.ToObject();
}
}
public class B
{
private A _formA;
public B(A formA)
{
_formA = formA;
}
private void GetDataSourceFromA()
{
object dataSource = _formA.GetDataSource();
}
}
This might lead to another problem though; the second form being on a different thread. Calling objects on the first form from a different thread is not possible, more info here, though I think out of scope for your question.
Thank you for your help. I found that Form1 GridView was set to private... i entered in the code behind Form1 and modified it to private.
Cheers.
Related
I am trying to chase a memory leak in a multiform C#.Net application, on Windows 7, VS 2008.
I found this SO post, which indicates that the second form's finalizer should be automatically called
this.Dispose() doesn't release memory used by Form after closing it.
However, it isn't working for me.
Each time a pop up the second form (which contains a large string, and a PictureBox), the amount of memory the app uses increases, even when I force a GC. Interestingly, the String's finalizer IS being called.
I've add a log to both form's Dispose methods; Form2's dispose is being called.
The code is
Form1 (main form)
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MemoryLeakTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
~Form1()
{
System.Diagnostics.Debugger.Log(0, "", "Form1.Destructor has been called.\n");
}
private void GC_Click(object sender, EventArgs e)
{
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
System.GC.Collect();
System.GC.WaitForPendingFinalizers();
}
private void OpenForm_Click(object sender, EventArgs e)
{
Form secondForm = null;
if (secondForm == null)
{
secondForm = new Form2();
secondForm.Show();
}
secondForm = null;
}
private void UpdateMemory_Click(object sender, EventArgs e)
{
long memory = System.GC.GetTotalMemory(false);
this.MemoryUsage.Text = "Memory usage: " +
String.Format("{0:n}", memory) +
" bytes";
}
private void AllocateString_Click(object sender, EventArgs e)
{
// StringWrapper wrapper = new StringWrapper();
}
}
public class StringWrapper
{
String str = new String('*', 1024 * 1024);
~StringWrapper()
{
System.Diagnostics.Debugger.Log(0, "", "StringWrapper finalizer has been called.\n");
}
}
}
and Form2 is
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace MemoryLeakTest
{
public partial class Form2 : Form
{
StringWrapper wrapper = new StringWrapper();
public Form2()
{
InitializeComponent();
this.pictureBox1.Image = Image.FromFile("C:/Windows/Web/Wallpaper/Windows/img0.jpg");
}
~Form2()
{
System.Diagnostics.Debugger.Log(0, "", "Form2.Finalizer has been called.\n");
}
}
}
I haven't included the designer generated code, but can add it if need be
I am playing around in visual studio and getting to know C# better. I am coming from an intermediate background knowledge of Java.
I have produced a very simple windows form application. The user clicks on a button, the button takes them to another screen, the user types into a textbox and presses a button in which that button will display what the user typed in; in the form. This is the code:
Form1.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form1 : Form
{
Form2 userinputForm;
public Form2 getSetForm2 {
get { return userinputForm; }
set { userinputForm = value; }
}
Form1 homeFormObj;
public Form1 getSetForm1 {
get { return homeFormObj; }
set { homeFormObj = value; }
}
public Form1()
{
InitializeComponent();
getSetForm2 = new Form2();
getSetForm1 = this;
getSetForm2.formOnePublicObj = getSetForm1;
}
internal void displayUserInput(string name)
{
Label l = new Label();
l.Text = name;
panel1.Controls.Add(l);
}
private void button1_Click(object sender, EventArgs e)
{
userinputForm.Show();
}
}
}
Form2.cs:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication3
{
public partial class Form2 : Form
{
Form1 formOneObj;
public Form1 formOnePublicObj {
get { return formOneObj; }
set { formOneObj = value; }
}
public Form2()
{
InitializeComponent();
}
List<string> userinputs = new List<string>();
private void button1_Click(object sender, EventArgs e)
{
string name = textBox1.Text;
formOnePublicObj.displayUserInput(name);
}
}
}
The error occurs the second time the user presses the button to go to form2. it occurs on the .show() method.
(P.S I coded like this to see how I can pass data from one windows form to another hence the getters and setters on the form objects).
Well, userinputform is never set and so is null. As such I don't understand why it works the first time unless this isn't actually your code pasted in.
It's probably because you're closing the second form, which is destroying it therefore you can't show it again. Each time you click the button in form1 create a new form2:
getSetForm2 = new Form2();
getSetForm1 = this;
getSetForm2.formOnePublicObj = getSetForm1;
This Form 1
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Diagnostics;
using System.Threading;
using Managed.Adb;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
AndroidDebugBridge mADB;
String mAdbPath;
List<Device> devices = AdbHelper.Instance.GetDevices(AndroidDebugBridge.SocketAddress);
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e )
{
//mAdbPath = Environment.GetEnvironmentVariable("PATH");
mAdbPath = "C:\\Users\\Nadun\\AppData\\Local\\Android\\android-sdk\\platform-tools";
mADB = AndroidDebugBridge.CreateBridge(mAdbPath + "\\adb.exe", true);
mADB.Start();
var list = mADB.Devices;
textBox1.Text = "" + list.Count;
foreach (Device item in list)
{
Console.WriteLine("");
listBox1.Items.Add("" + item.Properties["ro.build.product"].ToString() + "-" + item.SerialNumber.ToString() );
}
//Console.WriteLine("" + list.Count);
}
private void button2_Click(object sender, EventArgs e)
{
string text = listBox1.GetItemText(listBox1.SelectedItem);
Form2 f2 = new Form2(text);
// f2.Phone = "scs";
SetPhone sp = new SetPhone();
sp.PhoneModel = "Test";
this.Visible = false;
f2.ShowDialog();
}
}
}
This is Form 2
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
private string phone;
public string Phone
{
get { return this.phone; }
set { this.phone = value; }
}
public Form2(string a)
{
InitializeComponent();
textBox1.Text = a;
}
private void Form2_Load(object sender, EventArgs e)
{
//Form2 f2 = new Form2();
//f2.phone = "s";
//textBox1.Text = f2.Phone;
SetPhone sp = new SetPhone();
textBox1.Text = sp.PhoneModel;
Console.WriteLine("sefsef-"+sp.PhoneModel);
}
}
}
This is my Class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WindowsFormsApplication1
{
class SetPhone
{
private string phoneModel;
public string PhoneModel {
get { return this.phoneModel; }
set { this.phoneModel = value; }
}
}
}
Get always returning empty.i don't know why.
I am trying to set values from "form1".
i wrote class for that as well.but when i getting values from "form2" it returning empty.i don't know why
Your SetPhone class object which is calling the setter in the button2_click is a local variable, so when you try access the same in Form2_Load using another local variable, it is a completely new object and Get returns an empty string (default value). You should be able to share the SetPhone variable across forms, may be using constructor, then it will retain the values set using the setter
the goal of the program is to be able to use the get and set methods of variables.
I have this code in a project C#:
Form1:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
private int c = 0;
public int a { get; set; }
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
a = 5;
Form2 f2 = new Form2();
f2.b = a;
f2.Show();
}
}
}
and in a Form2:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Form1 f1 = new Form1();
MessageBox.Show(Convert.ToString(b));
}
}
}
This code not work because the value of b should be 5, but during execution value 0;
any solution?
You can't expect values of one instance to magically propagate to every other instance.
So doing this:
Form1 f1 = new Form1();
int b = f1.a;
Is always going to be 0. You created a new instance, and nothing has happened to it! If you want to get the existing form's value (where the button was presumably clicked) you need to pass it to Form2 somehow.
You can:
Pass it on the constructor of Form2
Set up a service that holds the data instead
Probably about a million other approaches
private void button1_Click(object sender, EventArgs e)
{
a = 5;
Form2 f2 = new Form2();
f2.b=a;
f2.Show();
}
public partial class Form2 : Form
{
public int b;
public Form2()
{
InitializeComponent();
}
}
You want to pass the data before showing the second form instead of after the fact.
On form close I call update but I got error message: update requires InsertCommand whereas I inspired from this tut http://www.switchonthecode.com/tutorials/csharp-tutorial-binding-a-datagridview-to-a-database
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
namespace datatablemsaccess
{
partial class Form1
{
OleDbDataAdapter dataAdapter;
private string getSQL() {
string sql = "SELECT * from tPerson";
return sql;
}
private string getConnectionString() {
string connectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + #"App_Data\person.mdb";
return connectionString;
}
private DataTable getDataTable(string sql)
{
DataTable dataTable;
string connectionString = getConnectionString();
using (dataAdapter = new OleDbDataAdapter(sql, connectionString))
{
dataTable = new DataTable();
dataAdapter.Fill(dataTable);
}
return dataTable;
}
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Data;
using System.Data.OleDb;
namespace datatablemsaccess
{
public partial class Form1 : Form
{
BindingSource bindingSource;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string sql = getSQL();
bindingSource = new BindingSource();
bindingSource.DataSource = getDataTable(sql);
dataGridView1.DataSource = bindingSource;
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
dataAdapter.Update((DataTable)bindingSource.DataSource);
}
}
}
You need to define an InsertCommand.
See Update requires a valid InsertCommand when passed DataRow collection with new rows