Timer1 not start when add new User Control.I have 1 User Control (UC_Machine).And when load Form Main I using timer execute SQL query in query variable to get data from table [tbl_FF_Trigger]
I have 1 User Control (UC_Machine).And when load Form Main I using timer execute SQL query in query variable to get data from table [tbl_FF_Trigger]
-Code in UC_Machine:
private void UC_Machine_Load(object sender, EventArgs e)
{
timer1.Start();
}
private void timer1_Tick(object sender, EventArgs e)
{
string query = "SELECT CRDName, PartNumber ,DefectName FROM [tbl_FF_Trigger] where Machine = '" + Machine + "'";
db.fillDataGridView(query, dataGridView1);
dataGridView1.BackgroundColor = Color.White;
dataGridView1.RowHeadersVisible = false;
dataGridView1.Update();
dataGridView1.Refresh();
}
Code in form MAIN. Will get the information of the machines from the function Machine_Infor.GetMachine_Infors(). It will then create a UC_Machine array from that information. If the machine in the array does not already exist in the panellayout, it will be added to the panellayout.
In addition, it also checks if the machine exists in the tbl_FF_Trigger table. Otherwise it will delete the machine from the panellayout.
private void Main_Load(object sender, EventArgs e)
{
Get_Infor();
}
private void Get_Infor()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 3000; // Thời gian chạy (5000 milliseconds = 5 second)
timer.Elapsed += Timer_Elapsed;
timer.Start();
}
private void Timer_Elapsed(object sender, ElapsedEventArgs e)
{
// Add new item to panellayout if machine have falsecall
var data = Machine_Infor.GetMachine_Infors();
var list = new UC_Machine[data.Count];
int i = 0;
itemFoods = new List<UC_Machine>();
itemFoodsFilter = new List<UC_Machine>();
HashSet<string> existingMachine = new HashSet<string>();
foreach (var item in data)
{
if (!existingMachine.Contains(item.Machine))
{
bool isExisting = false;
foreach (UC_Machine uc in myFlowLayoutPanel1.Controls)
{
if (uc.Machine == item.Machine)
{
isExisting = true;
break;
}
}
if (!isExisting)
{
list[i] = new UC_Machine();
list[i].CRDName = item.CRDName;
list[i].Model = item.Model;
list[i].Machine = item.Machine;
list[i].PartNumber = item.PartNumber;
list[i].Workcell = item.Workcell;
list[i].CRDName = item.CRDName;
list[i].Date = item.Date;
itemFoods.Add(list[i]);
itemFoodsFilter.Add(list[i]);
existingMachine.Add(item.Machine);
i++;
}
}
}
if (myFlowLayoutPanel1.InvokeRequired)
{
myFlowLayoutPanel1.Invoke((MethodInvoker)delegate
{
myFlowLayoutPanel1.Controls.AddRange(list.Where(x => x != null).ToArray());
});
}
else
{
myFlowLayoutPanel1.Controls.AddRange(list.Where(x => x != null).ToArray());
}
// Remove machine if Falsecall not found
string maincon = ConfigurationManager.ConnectionStrings["Connstring"].ConnectionString;
// Connect to the SQL Server database and execute the query to check for the existence of "vnhcmsleaoi05" in the "tbl_FF_Trigger" table.
using (SqlConnection connection = new SqlConnection(maincon))
{
connection.Open();
foreach (UC_Machine uc in myFlowLayoutPanel1.Controls)
{
string query = "SELECT COUNT(*) FROM tbl_FF_Trigger WHERE Machine = '"+ uc.Machine+"'";
using (SqlCommand command = new SqlCommand(query, connection))
{
int count = (int)command.ExecuteScalar();
if (count == 0)
{
if (myFlowLayoutPanel1.InvokeRequired)
{
myFlowLayoutPanel1.Invoke((MethodInvoker)delegate
{
myFlowLayoutPanel1.Controls.Remove(uc);
itemFoods.Remove(uc);
uc.Dispose();
});
}
else
{
myFlowLayoutPanel1.Controls.Remove(uc);
itemFoods.Remove(uc);
uc.Dispose();
}
break;
}
}
}
}
}
Code working OK when load Form. when tbl_FF_Trigger add new value myFlowLayoutPanel1 new UC_Machine
but timer1 not start. I know this because the datagirdview has no data in the newly added UC_Machine.I want when myFlowLayoutPanel1 adds 1 UC_Machine, timer1 will start
Anyone have any advise or solution for this case, please help me. Thanks a lot!
Your question is how to call timer in UC Control in Form Main. The main form is trying to GetInfo from the UC but consider that this might be "backwards" and that the UC Control should be notifying Form Main when it gets the new info instead. Here's what I mean:
Your UC has its own timer1 (we'll get timer1 started don't worry). What main form needs is to be notified when a new query is available in one of the UCs. Giving main form its own timer will interfere with an otherwise-orderly process. Consider making an event in your UC as shown and fire it whenever UC is done getting a new query.
UserControlMachine
Example: UC starts its own timer1 and fires RecordsChanged event when new query completes.
public partial class UserControlMachine : UserControl
{
public UserControlMachine()=>InitializeComponent();
public BindingList<Record> Records { get; } = new BindingList<Record>();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
timer1 = new Timer { Interval = 2500 };
timer1.Tick += onTimer1Tick;
timer1.Start();
dataGridView1.DataSource = Records;
Records.Add(new Record()); // <- Auto-generate columns
dataGridView1.Columns[nameof(Record.DefectName)].AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill;
}
private System.Windows.Forms.Timer timer1;
private void onTimer1Tick(object sender, EventArgs e) => queryDB();
private void queryDB()
{
// S I M U L A T E D Q U E R Y R E S U L T
Records.Clear();
for (int i = 0; i < Rando4Test.Next(1,5); i++)
{
Records.Add(new Record
{
CRDName = $"CRD-{(char)Rando4Test.Next(65,70)}{Rando4Test.Next(100, 200)}"
});
}
// Notify the Main Form that something has changed.
RecordsChanged?.Invoke(this, EventArgs.Empty);
}
public event EventHandler RecordsChanged;
// For testing purposes
public static Random Rando4Test { get; } = new Random();
}
Main Form
All the main form has to do is listen for RecordsChanged events.
public partial class Form1 : Form
{
public Form1() => InitializeComponent();
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
// Simulation: Add 2 machines
for (int i = 0; i < 2; i++)
{
var machine = new UserControlMachine
{
Size = new Size(myFlowLayoutPanel1.Width - SystemInformation.VerticalScrollBarWidth, 200),
BorderStyle = BorderStyle.FixedSingle,
};
myFlowLayoutPanel1.Controls.Add(machine);
// Listen for new query results
machine.RecordsChanged += onAnyUCRecordsChanged;
}
}
private void onAnyUCRecordsChanged(object sender, EventArgs e)
{
int totalDefects = 0;
foreach (var machine in myFlowLayoutPanel1.Controls.OfType<UserControlMachine>())
{
totalDefects += machine.Records.Count;
}
Text = $"Main Form - Total Defects: {totalDefects}";
}
}
WHERE Record class represents a DataGridViewRow
public class Record
{
public string PartNumber { get; set; } =
Guid.NewGuid().ToString().Substring(0, 13).ToUpper();
public string CRDName { get; set; }
public string DefectName { get; set; } = "Unknown Error";
}
Related
I have a form opens up a dialog that contains a DataGridView.
When I double click the DataGridView, it opens up a child form that contains details of that row.
Once I save any updates, the child form closes and the DataGridView should be refreshed.
However, I have noticed that the DataGridView's refresh function is not getting the right data back from the database. It is getting the data from BEFORE the update and not AFTER the update thus displaying incorrect data.
I am unsure of how to continue on from here as my current method is to refresh the DataGridView directly from the Child Form
Here is my Code
This is the double click action to open the child form
private void fieldsDataGridView_DoubleClick(object sender, EventArgs e)
{
foreach (DataGridViewRow row in fieldsDataGridView.SelectedRows)
{
fieldIdInput.Text = row.Cells["Id"].Value.ToString();
DialogResult dr = new DialogResult();
EditFields editFields = new EditFields(this,programIdInput.Text, fieldIdInput.Text, false);
editFields.Show();
}
}
This is the Refresh function contained on the first form
public void RefreshDataGrid()
{
var selected = programInput.SelectedValue;
if (selected != null)
{
var result = programsData.Get(selected.ToString());
if (result != null)
{
programIdInput.Text = result.Id;
LoadList(result.Id);
}
}
if (selected == "-1")
{
RecursiveClearInputs(this.Controls);
programIdInput.Text = "";
fieldIdInput.Text = "";
fieldsDataGridView.DataSource = null;
}
fieldsDataGridView.Refresh();
fieldsDataGridView.ClearSelection();
}
private void LoadList(string Input)
{
fieldsDataGridView.DataSource = null;
List<Field> fields = new List<Field>();
fields = fieldsData.GetAllByTaskId(Input);
List<FieldsDGViewModel> fdgvm = new List<FieldsDGViewModel>();
foreach (var item in fields)
{
var f = new FieldsDGViewModel
{
Id = item.Id,
Name = item.Name,
Order = item.Order,
IsPrint = item.IsPrint
};
fdgvm.Add(f);
}
fdgvm = fdgvm.OrderBy(x => x.Order).ToList();
fieldsDataGridView.DataSource = fdgvm;
fieldsDataGridView.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
fieldsDataGridView.Columns["Id"].Visible = false;
fieldsDataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
}
This is the child forms constructor
private string ProgramId;
private string FieldId;
private bool IsNew;
private Fields Field;
ProgramsData programsData = new ProgramsData();
FieldsData fieldsData = new FieldsData();
PrinterData printerData = new PrinterData();
public EditFields(Fields Field, string ProgramId, string FieldId, bool IsNew)
{
this.ProgramId = ProgramId;
this.FieldId = FieldId;
this.IsNew = IsNew;
this.Field = Field;
InitializeComponent();
this.FormClosing += new FormClosingEventHandler(this.EditFields_FormClosing);
}
This is the Child Forms closing function
private void EditFields_FormClosing(object sender, FormClosingEventArgs e)
{
Field.RefreshDataGrid();
}
I have a project and I'm locked. I open different forms on Form1 you see below in the code. I did this with "notifyIcon". Instead of opening 5 different forms, I am bringing one by changing the form. I have 5 forms on my screen. But my problem is; I can save the locations of the forms. Technically they all come from the same form, so they all start from the same position. Do you have a recommendation?
Edit :
A new idea came to mind. but I need your help again. when I close the form, I can save the form's position to a TxT file and manually start the positions with the positions from TxT when the forms are opened.
private void Form1_Load(object sender, EventArgs e)
{
this.Hide();
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
}
private void tCKToolStripMenuItem_Click(object sender, EventArgs e)
{
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
string tckRenk = satirlar[0];
Color tckColor = System.Drawing.ColorTranslator.FromHtml(tckRenk);
Form2 tckForm = new Form2();
tckForm.Opacity = .50;
tckForm.TopMost = true;
tckForm.BackColor = tckColor;
tckForm.LabelText = "TCK";
tckForm.Show();
}
private void aDAToolStripMenuItem_Click(object sender, EventArgs e)
{
string dosyaYolu = #"D:\color\colors.txt";
string[] satirlar = File.ReadAllLines(dosyaYolu);
string adaRenk = satirlar[1];
Color adaColor = System.Drawing.ColorTranslator.FromHtml(adaRenk);
Form2 adaForm = new Form2();
adaForm.Opacity = .50;
adaForm.TopMost = true;
adaForm.BackColor = adaColor;
adaForm.LabelText = "ADA";
adaForm.Show();
}
You can set From Location
Form frm2 = new Form();
frm2.StartPosition = FormStartPosition.Manual;
frm2.Left = 500;
frm2.Top = 500;
frm2.Show();
public static class extensions
{
public static void SaveFormSizeAndLocation(this Form form)
{
try
{
using (RegistryKey key = Application.UserAppDataRegistry.CreateSubKey(form.Name))
{
if (key != null)
{
if (form.WindowState == FormWindowState.Normal)
{
key.SetValue("Left", form.Left);
key.SetValue("Top", form.Top);
key.SetValue("Width", form.Width);
key.SetValue("Height", form.Height);
}
if (form.ShowInTaskbar)
{
string windowState = Enum.GetName(typeof(FormWindowState), form.WindowState);
key.SetValue("WindowState", form.WindowState);
}
}
}
}
catch
{
// Party on, Garth!
}
}
public static void LoadFormSizeAndLocation(this Form form)
{
try
{
using (RegistryKey key = Application.UserAppDataRegistry.OpenSubKey(form.Name))
{
if (key != null)
{
form.Left = (int)key.GetValue("Left", form.Left);
form.Top = (int)key.GetValue("Top", form.Top);
form.Width = (int)key.GetValue("Width", form.Width);
form.Height = (int)key.GetValue("Height", form.Height);
// Move window into visible screen bounds if outside screen bounds (prevent off-screen hidden windows)
Rectangle screenRect = SystemInformation.VirtualScreen;
if (form.Left < screenRect.Left)
form.Left = screenRect.Left;
if (form.Top < screenRect.Top)
form.Top = screenRect.Top;
if (form.Right > screenRect.Right)
form.Left = screenRect.Right - form.Width;
if (form.Bottom > screenRect.Bottom)
form.Top = screenRect.Bottom - form.Height;
if (form.ShowInTaskbar)
{
string windowState = Enum.GetName(typeof(FormWindowState), form.WindowState);
windowState = key.GetValue("WindowState", windowState).ToString();
form.WindowState = (FormWindowState)Enum.Parse(typeof(FormWindowState), windowState);
}
}
}
}
catch
{
// Party on, Wayne!
}
}
}
Use this extension methods and call it on form shown, form Closing & form Move events
For Complete Working Sample
public partial class Form3 : Form
{
private int count = 1;
public Form3()
{
InitializeComponent();
}
private void Form2_Move(object sender, EventArgs e)
{
this.SaveFormSizeAndLocation();
}
protected override void OnShown(EventArgs e)
{
Text = Name;
base.OnShown(e);
this.LoadFormSizeAndLocation();
this.Move += Form2_Move;
}
protected override void OnFormClosing(FormClosingEventArgs e)
{
base.OnFormClosing(e);
this.SaveFormSizeAndLocation();
}
private void button1_Click(object sender, EventArgs e)
{
var frm = new Form3();
frm.Name = "inner" + count.ToString();
frm.Show();
count++;
}
}
enter image description here
namespace Implementer
{
public partial class MainForm : Form
{
#region intit and globals
public MainForm()
{
InitializeComponent();
DevExpress.XtraGrid.Views.Grid.GridView gridView = new DevExpress.XtraGrid.Views.Grid.GridView();
var transactions = new ObservableCollection<Item>();
for (int i = 0; i <= 100; i++)
{
transactions.Add(new Item { Content = "Item " + i });
}
grdTransactions.AllowDrop = true;
grdTransactions.DataSource = transactions;
dgmWf.AddingNewItem += (s, e) => transactions.Remove(e.Item.Tag as Item);
}
Point mouseDownLocation;
GridHitInfo gridHitInfo;
#endregion
#region events
public void Mainform_Load(object sender, EventArgs e)
{
// TODO: This line of code loads data into the 'vA_ERP4_ADMINDataSet.SYSTEM_MODULES' table. You can move, or remove it, as needed.
//Project initiation
//Fill drop down for project list
cmbProject.SelectedIndex = 0;
DataAccess dataAccess = new DataAccess(GlobalFunctions.GetConnectionString());
DataTable dtResult = dataAccess.ExecuteQueryDataSet("select MODULE_CODE, MODULE_DESC from SYSTEM_MODULES where module_is_active=1").Tables[0];
cmbProject.DisplayMember = "MODULE_DESC";
cmbProject.ValueMember = "MODULE_CODE";
cmbProject.DataSource = dtResult;
}
private void cmbProject_SelectedIndexChanged(object sender, EventArgs e)
{
lblCurrentProject.Text = cmbProject.Text;
if (cmbProject.Text != null)
{
DataAccess dataAccess = new DataAccess(GlobalFunctions.GetConnectionString());
DataTable dtTransactions = dataAccess.ExecuteQueryDataSet("select sys_trans_id, sys_trans_desc1 from WF_SYSTEM_TRANS where MODULE_CODE= '" + cmbProject.Text + "'").Tables[0];
grdTransactions.DataSource = dtTransactions;
}
}
private void btnSalesInvoice_Click(object sender, EventArgs e)
{
int sysTransId = 1001;
FillTransactionDetails(sysTransId);
}
#endregion
#region drag drop
private void grdTransactions_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && CanStartDragDrop(e.Location))
{
StartDragDrop();
}
}
private void grdTransactions_MouseDown(object sender, MouseEventArgs e)
{
gridHitInfo = grdVTransactions.CalcHitInfo(e.Location);
mouseDownLocation = e.Location;
}
private void grdTransactions_MouseLeave(object sender, EventArgs e)
{
if (gridHitInfo != null)
gridHitInfo.View.ResetCursor();
gridHitInfo = null;
}
private bool CanStartDragDrop(Point location)
{
return gridHitInfo.InDataRow && (Math.Abs(location.X - mouseDownLocation.X) > 2 || Math.Abs(location.Y - mouseDownLocation.Y) > 2);
}
public void StartDragDrop()
{
var draggedRow = gridHitInfo.View.GetRow(gridHitInfo.RowHandle) as Item;
var tool = new FactoryItemTool(" ", () => " ", diagram => new DiagramShape(BasicShapes.Rectangle) { Content = draggedRow.Content, Tag = draggedRow }, new System.Windows.Size(150, 100), false);
dgmWf.Commands.Execute(DiagramCommandsBase.StartDragToolCommand, tool, null);
}
#endregion
#region function
private void FillTransactionDetails(int systemTransactionId)
{
//Fill document
//Fill steps
DataAccess dataAccess = new DataAccess(GlobalFunctions.GetConnectionString());
DataTable transactionDetails = dataAccess.ExecuteQueryDataSet("SELECT DOC_TYPE_DESC1 FROM WF_SYSTEM_TRANS_DT WHERE SYS_TRANS_ID=1001 and MODULE_CODE= '" + cmbProject.Text + "'").Tables[0];
transactionDetails.Rows.Add();
grdDocuments.DataSource = transactionDetails;
grdDocuments.Columns["Details"].DisplayIndex = 2;
grdDocuments.Columns["Delete"].DisplayIndex = 2;
DataTable transactionSteps = dataAccess.ExecuteQueryDataSet("select WF_STEP_DESC1 from WF_STEPS where wf_id= 10101 and MODULE_CODE= '" + cmbProject.Text + "'").Tables[0];
transactionSteps.Rows.Add();
grdSteps.DataSource = transactionSteps;
}
#endregion
}
public class Item
{
public string Content { get; set; }
}
}
I don't really know where is the mistake and have been looking at it for the past few days and searching for an answer but no luck so I'd be so happy if you could help me out. It was working without the data fetching. but after calling the data it doesn't work. drag it from the grid view and when it reaches the diagram control it would turn into a rectangle with a tag property of it's ID.. With regards to the connection string.. I created a global function to just call it on the main form.
The problem I'm having is where I can successfully use the RoomID of the Room object I've created, but not the panel. Here is the function where I set the label to the name of the room. (This is my Form1.cs)
public partial class Form1 : Form
{
Room ThisRoom = new Room();
public Form1()
{
InitializeComponent();
this.Text = "Aquinas College Master Controller";
}
private void roomDesignerToolStripMenuItem_Click(object sender, EventArgs e)
{
new RoomDesigner().Show();
}
private void button1_Click(object sender, EventArgs e)
{
roomsToolStripMenuItem.DropDownItems.Clear();
foreach (var Room in Global.Aquinas.Aquinas)
{
ToolStripMenuItem NewItem = new ToolStripMenuItem(Room.RoomID);
NewItem.Name = Room.RoomID;
NewItem.Click += new EventHandler(ItemClick);
roomsToolStripMenuItem.DropDownItems.Add(NewItem);
}
}
void ItemClick(object sender, EventArgs e)
{
ToolStripItem item = (ToolStripItem)sender;
label2.Text = item.Name;
foreach (var Room in Global.Aquinas.Aquinas)
{
if (Room.RoomID == item.Name)
{
ThisRoom = Room;
break;
}
}
Panel RoomPanel = ThisRoom.Panel;
RoomPanel.Size = new Size(607, 304);
RoomPanel.Location = new Point(144, 27);
RoomPanel.BackColor = Color.White;
this.Controls.Add(RoomPanel);
}
}
This is some of my code for the room object. (This is in Room.cs)
public class Room
{
private List<CtrlComputer> _Computers;
public List<CtrlComputer> Computers
{
get { return _Computers; }
set { _Computers = value; }
}
private string _RoomID;
public Room()
{
_Computers=new List<CtrlComputer>();
}
public string RoomID
{
get
{
return _RoomID;
}
set
{
_RoomID = value;
}
}
public Panel Panel
{
get
{
return _Panel;
}
set
{
_Panel = value;
}
}
private Panel _Panel;
}
And here is where I register the panel which I have just put my designs on, to a new room. (This is some of my RoomDesigner.cs)
public partial class RoomDesigner : Form
{
Room NewRoom = new Room();
Panel RoomDesignerPanel = new Panel();
public RoomDesigner()
{
InitializeComponent();
RoomDesignerPanel.Size = new Size(607, 304);
RoomDesignerPanel.Location = new Point(144, 27);
RoomDesignerPanel.BackColor = Color.White;
this.Controls.Add(RoomDesignerPanel);
textBox1.ForeColor = SystemColors.GrayText;
textBox1.Text = "Enter Computer ID Here";
this.textBox1.Leave += new System.EventHandler(this.textBox1_Leave);
this.textBox1.Enter += new System.EventHandler(this.textBox1_Enter);
textBox2.ForeColor = SystemColors.GrayText;
textBox2.Text = "Enter Room ID Here";
this.textBox2.Leave += new System.EventHandler(this.textBox2_Leave);
this.textBox2.Enter += new System.EventHandler(this.textBox2_Enter);
}
private void textBox1_Leave(object sender, EventArgs e)
{
if (textBox1.Text.Length == 0)
{
textBox1.Text = "Enter Computer ID Here";
textBox1.ForeColor = SystemColors.GrayText;
}
}
private void textBox1_Enter(object sender, EventArgs e)
{
if (textBox1.Text == "Enter Computer ID Here")
{
textBox1.Text = "";
textBox1.ForeColor = SystemColors.WindowText;
}
}
private void textBox2_Leave(object sender, EventArgs e)
{
if (textBox2.Text.Length == 0)
{
textBox2.Text = "Enter Room ID Here";
textBox2.ForeColor = SystemColors.GrayText;
}
}
private void textBox2_Enter(object sender, EventArgs e)
{
if (textBox2.Text == "Enter Room ID Here")
{
textBox2.Text = "";
textBox2.ForeColor = SystemColors.WindowText;
}
}
private void button1_Click(object sender, EventArgs e)
{
CtrlComputer NewComputer = new CtrlComputer();
NewComputer.ComputerID = textBox1.Text;
NewComputer.Text = NewComputer.ComputerID;
NewComputer.Parent = RoomDesignerPanel;
RoomDesignerPanel.Controls.Add(NewComputer);
NewRoom.Panel = RoomDesignerPanel;
NewRoom.Add(NewComputer);
}
When I try to reload that panel, the RoomID of that object is returned fine, yet the panel is not. Any ideas?
Edit: Sorry for the lack of clarity in my post, first posts aren't always easy.
The panel is created in the designer, but I tried private Panel Panel1 = new Panel(); with no luck. My current problem is that in Form1.cs, the program will throw "Cannot access a disposed object", but I followed the guide here https://msdn.microsoft.com/en-us/library/82785s1h(v=vs.110).aspx .
What you are looking to do is swap between a collection of Panel objects (kind of like your own version of TabPages). To do this you need to create each of the Panel objects (You do this in RoomDesigner, which is fine, but there is a catch: see * below). With that collection in hand, when you want to show it on the form, you need to remove the panel1 the designer code created (Controls.Remove(panel1)) and insert your new one (Controls.Add(RoomPanel)).
Since Controls utilize system resources, make sure to Dispose any control you will no longer use. Here is an example method:
//Initial case where no room has been displayed yet and panel1 is still valid
private Panel CurrentPanel = null;
public void SwapPanel(Panel p)
{
//If no panel has been placed yet, get rid of the default one
if (panel1 != null)
{
//we should never need the designer panel again, so dispose it
panel1.Dispose();
this.Controls.Remove(panel1);
}
else
{
//we may return to this panel later, so don't dispose it
this.Controls.Remove(CurrentPanel);
}
CurrentPanel = p;
this.Controls.Add(p);
}
When you finally close out and no longer need your Panels stored in your Room collection, make sure to Dispose them. (However, if your whole program is exiting at that point then it doesn't matter, but do it anyway as good practice)
*When you close any RoomDesigner form (or any form), all controls it contains in 'Controls' will be disposed, even if you are using them elsewhere. To prevent this, remove the controls you want to preserve from the RoomDesigner Controls collection before it is closed.
Im adding objects to a datagridview ( only one kind) through a list
ej.
List<Material> mater = new List<Material>();
DataGridView dgvMAterial = new DataGridView();
dgvMaterial.DataSource = null;
mater.Add((Material)cmbMaterial.SelectedValue);
dgvMaterial.DataSource = mater;
But every time I click over the datagrid I get an indexoutofrangeexeption.
Can somone tell me why?
thanks
here is my whole code for the form
public partial class inicio : Form
{
private string ConnectionString = "Data Source=localhost\\sqlexpress;Initial Catalog=data.mdf;Integrated Security=SSPI;";
//private string ConnectionString = "Server=.\\SQLExpress;AttachDbFilename=|DataDirectory|\\data\\data_data.mdf.mdf; Database=data.mdf;Trusted_Connection=Yes;";
private ISessionFactory sessionFactory;
List<Material> mater = new List<Material>();
List<Salarios> salar = new List<Salarios>();
IBindingList mind = new BindingList<Salarios>();
Productos prod;
public inicio()
{
InitializeComponent();
sessionFactory = nhn.BusinessObjects.Initialize.CreateSessionFactory(ConnectionString);
dgvMaterial.DataSource = mater;
}
private void materialToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmMaterial material = new costeos.Catalogos.frmMaterial(ConnectionString);
material.ShowDialog(this);
material.Dispose();
}
private void salariosToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmSalarios salarios = new costeos.Catalogos.frmSalarios(ConnectionString);
salarios.ShowDialog(this);
salarios.Dispose();
}
private void agregarToolStripMenuItem_Click(object sender, EventArgs e)
{
Catalogos.frmAddRemuneraciones rem = new costeos.Catalogos.frmAddRemuneraciones(ConnectionString);
rem.ShowDialog(this);
rem.Dispose();
}
private void agregarToolStripMenuItem1_Click(object sender, EventArgs e)
{
Catalogos.frmAddAdmin adm = new costeos.Catalogos.frmAddAdmin(ConnectionString);
adm.ShowDialog(this);
adm.Dispose();
}
private void agregarToolStripMenuItem2_Click(object sender, EventArgs e)
{
Catalogos.frmAddInsumosInd insumos = new costeos.Catalogos.frmAddInsumosInd(ConnectionString);
insumos.ShowDialog(this);
insumos.Dispose();
}
private void txt_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsDigit(e.KeyChar) || char.IsPunctuation(e.KeyChar) || char.IsControl(e.KeyChar))
{
e.Handled = false;
}
else
{
e.Handled = true;
}
}
private void inicio_Load(object sender, EventArgs e)
{
LlenaCampos();
}
private void LlenaCampos()
{
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
var mat = session.CreateCriteria(typeof(Material))
.List<Material>();
var sal = session.CreateCriteria(typeof(Salarios))
.List<Salarios>();
transaction.Commit();
cmbMaterial.DataSource = mat;
cmbMaterial.DisplayMember = "Nombre";
cmbSalarios.DataSource = sal;
cmbSalarios.DisplayMember = "Nombre";
cmbMIndirecta.DataSource = sal;
cmbMIndirecta.DisplayMember = "Nombre";
}
}
}
private void btnAddMaterial_Click(object sender, EventArgs e)
{
materialBindingSource.DataSource = null;
//dgvMaterial.DataSource = null;
mater.Add((Material)cmbMaterial.SelectedValue);
//dgvMaterial.DataSource = mater;
dgvMaterial.DataSource = materialBindingSource;
materialBindingSource.DataSource = mater;
materialBindingSource.ResetBindings(false);
}
private void button2_Click(object sender, EventArgs e)
{
dgvSalarios.DataSource = null;
salar.Add((Salarios)cmbSalarios.SelectedValue);
dgvSalarios.DataSource = salar;
}
private void button3_Click(object sender, EventArgs e)
{
dgvMIndirecta.DataSource = null;
mind.Add((Salarios)cmbMIndirecta.SelectedValue);
dgvMIndirecta.DataSource = mind;
}
private void button1_Click(object sender, EventArgs e)
{
using (var session = sessionFactory.OpenSession())
{
using (var transaction = session.BeginTransaction())
{
if (prod == null)
{
prod = new Productos { CargasTurno = float.Parse(txtCargasTurno.Text), CavidadesMolde = int.Parse(txtCavidadesMolde.Text), Clave = txtClave.Text, Comentarios = txtComentarios.Text, MezclasTurno = float.Parse(txtMezclasTurno.Text), Moldes = int.Parse(txtMoldes.Text), Nombre = txtNombre.Text, Peso = float.Parse(txtPesoTotal.Text), TotalPza = int.Parse(txtPzasTotales.Text), Turnos = int.Parse(txtTurnos.Text) };
session.Save(prod);
transaction.Commit();
}
foreach (DataGridViewRow dr in dgvMaterial.Rows)
{
Material m = dr.DataBoundItem as Material;
m.Materiales
PMaterial mat = new PMaterial { Material = dr.DataBoundItem as Material, Cantidad = float.Parse(dr.Cells["Cantidad"].Value.ToString()), Fecha = DateTime.Now, Producto = prod };
session.Save(mat);
}
transaction.Commit();
session.Close();
}
}
}
}
}
That's probably not DGV problem, but with this combo box. Show us the code that fills combo box and sets its properties.
If you are casting to Material class you should probably use SelectedItem instead of SelectedValue. (unless you exactly know what you're doing)
I would guess that you have an event-handler that isn't happy. What exactly does the message say?
You might also be having problems if you are adding the same Material instance to the list multiple times; since IndexOf will only find the first occurrence. This line makes me very suspicious:
mater.Add((Material)cmbMaterial.SelectedValue);
since it could potentially (on consecutive clicks / etc) do exactly this.
Note: if you used BindingList<T> instead all you'd have to doo is Add(...) - no resetting required:
field:
BindingList<Material> mater = new BindingList<Material>();
init grid:
dgvMaterial.DataSource = mater;
add item:
mater.Add(newInstance);
If you assign data source to the DGV you should check element count - if zero then assign null. I don't know why this is the way it is, but I'm doing it in all my forms.
//I'm still analysing the rest of the code