0

I have this code, in which I read the data i deserialized in a gridview, let's name it FormReadDatabases It gets populated like this:

xmlData = (xml.ServiceConfig)serializer.Deserialize(reader);
dataGridView1.DataSource = xmlData.Databases;

Then in each row of the grid I have a button 'Tables'
After I click it a new form appears FormReadTables

It gets populated like this:

BindingList<xml.Table> table = new BindingList<xml.Table>();
dataGridView4.DataSource = table;

Then I have a button which helps me add a new table, it works fine, the new row appears in the FormReadTables, But when i close the form and I am now at the FormReadDatabases if I click again on the Table button the changes are not saved.

Any idea how to avoid this?

Perf
  • 23
  • 1
  • 8
  • `static` or some runtime-manager (aka IoC singleton)? just sayin' ... –  Oct 22 '14 at 09:19
  • Dear @AndreasNiedermair Thanks for the reply but i'm a beginner, what do you mean by this? – Perf Oct 22 '14 at 09:24
  • which UI framework do you work with? –  Oct 22 '14 at 09:29
  • Your comment kinda gives the impression that you don't know the keyword `static`, so please read it up: http://msdn.microsoft.com/en-us/library/98f28cdx.aspx. Anyway, there are several techniques to mimic a *static* behavior, `static` being just one option though. –  Oct 22 '14 at 09:34
  • possible duplicate of [C# - Winforms - Global Variables](http://stackoverflow.com/questions/1293926/c-sharp-winforms-global-variables) –  Oct 22 '14 at 09:36

2 Answers2

2

This should be simple, data binding needs to happen using a mechanism that can hold value even when forms are opened or closed:

First way could be use a static type as follows:

static BindingList<xml.Table> table;

public BindingList<xml.Table> FetchTable()
{
if(table == null)
{
 table = new BindingList<xml.Table>();
}
return table
}

dataGridView4.DataSource = FetchTable();

There's a catch out here what if the form can have multiple instances than can access the static variable, then while updating the table type it needs to be locked / synchronized

Another option would be table type is part of the main form, which loads the child form and in the constructor of the child form it gets the instance of the parent form, which is used updated and is retained even after closing child form. This will also need synchronization for multiple user / thread access

public class ParentForm
{
public BindingList<xml.Table> table = new BindingList<xml.Table>();
}

public class ChildForm
{
ParentForm localPf;
pulic ChildForm(ParentForm pf)
{
localPf = pf;
}
dataGridView4.DataSource = localPf.table;
}

Noe any change to parent form object's table variable will persist till the point Parent form is in the memory, but please note this implementation is not yet threads safe

Mrinal Kamboj
  • 11,300
  • 5
  • 40
  • 74
1

Each time the form opens, you are creating a new BindingList.

BindingList<xml.Table> table = new BindingList<xml.Table>();

Instead, have the other page contain a variable for this, and when you 'new' the other form, pass in the variable.

The Actions taken on the opened form are byref, and therefore will update your host forms variable. This means the next time you open the form, the variable you pass to it will already have the previous changes already stored in it.

Example as requested:

I don't have my WinForms environment at hand, but this shows the important concepts.

namespace Bob
{
    public class FormLucy
    {
        private BindingList<xml.Table> table = new BindingList<xml.Table>();

        // your form stuff.. 

        protected void ButtonClick(object sender, EventArgs e)
        {
            var frm = new FormTracy(table);

            // init your forms properties, position etc

            fmr.ShowDialog();
        }
    }
}
atom.gregg
  • 987
  • 8
  • 14
  • This is what i need, could you please give me an example by code because i am new to this – Perf Oct 22 '14 at 09:25
  • But what if the other page isn't *static* either and can be opened and closed too... do you inject the `table` variable from the outermost page? And what, if the OP is working with ASP.NET and not eg WinForms? –  Oct 22 '14 at 09:28
  • @AndreasNiedermair yes, every page can be opened and closed, so i need to save in memory, i'm workking with WinForms – Perf Oct 22 '14 at 09:31
  • @Perf "in memory" is very vague, because *everything* (at some point) is in memory ... –  Oct 22 '14 at 09:32
  • @AndreasNiedermair, in memory i mean that, at the end i need to serialize the changes done to a new xml, so all the changes should be saved in memory before the first window closes – Perf Oct 22 '14 at 09:34
  • @Perf, declare your `table` variable inside the host forms class declaration. You can initialize it with the `new` keyword directly, or `new` it in the form constructor. When you `new` the other form, pass it into the constructor, then call Show or ShowDialog, whatever you are using. In the other form, either directly assign the variable to the DataSource property or assign it to a local variable that then assigns to the DataSource. What you choose here depends on your Needs, These are not copies of the variable just pointers. – atom.gregg Oct 22 '14 at 09:37
  • @AndreasNiedermair, perhaps the OP has since added it, but the question is tagged with WinForms. I personally would not have static forms lying around my application because my WinForms architecture doesn't need it. – atom.gregg Oct 22 '14 at 09:39
  • @Perf, regarding Memory usage: pay Attention and be thorough (using Statements, dispose correctly etc), but in your case don't worry too much (premature optimization is the root of all evil). Plus, what you are doing here is assigning pointers to a single memory space, not copying it. – atom.gregg Oct 22 '14 at 09:40
  • I did add the tag, and I did never ever talk about static forms ;) –  Oct 22 '14 at 09:41