0

I've tried seeing this: DataGridView bound to a Dictionary

But it's not exactly what I'm looking for, so here I am.

I have a dictionary like this (just an example of how it looks like):

{
    "file": 
    {
        "var-type": 
            {
                "var1": 
                       {
                           "description": "the description here",
                           "length": "the length here",
                           "type": "the type here",
                           "line": "the line number here",
                       }
            }
    }
}

And would like to have a DataGridView (real-time, thus binding it) that looks like this:

+------+-----------------+-----------------+---------------+
| Name |   Description   |     Length      |     Type      |
+------+-----------------+-----------------+---------------+
| var1 | the description | the length here | the type here |
+------+-----------------+-----------------+---------------+

This DataGridView will be in a TabPage (inside a TabController, and that tab page's name is var-type)

At first I had a dictionary, and every time the user wanted a DataGridView of it, the DataGridView would be made again and again from zero.

So when the user changes something, they have to reopen the DataGridView or refresh it manually in order to see the new changes. I don't want this. So I tried having DataTables for each var-type (and using a Dictionary as a DataTable collection, and the user would get real-time changes whenever they edit something.

That worked pretty well. But when it comes to editing a specific var's information, I would have to use .Select() (and I can't store the line number in the same DataTable). I would like to avoid this, so I went back to a one-dictionary-for-all again. I also heard that a dictionary is much more lightweight.

I've also tried storing the line number for each variable when using DataTables to avoid .Select(), but I also have some problems with this method, and would really prefer to have a dictionary instead.

I don't want to make the DataGridView and use a for loop each time the user wants to see it (hence I went with DataTables as properties that I can access anywhere, and just use them as DataSource whenever I want to display them), I just want to be able to use them whenever I want. Is this possible?

Just for the record; yeah this is a parser. And thanks a lot!

Rookie
  • 5
  • 3
  • Yes, I answer postings like this all the time. It looks like you have JSON, but do not see the classes for the object (nor dictionary). I can easily post code to turn you LIst() object into a datatable but do not presently have enough info to accomplish the task. – jdweng Apr 22 '19 at 11:42
  • It's not an actual JSON, it was just an example to make it readable. It's a dictionary. I want to avoid for-looping each time, thanks again. – Rookie Apr 22 '19 at 11:46

1 Answers1

1

Use one of the following :

            DataTable dt = new DataTable();

            Dictionary<string, DataRow> dict1 = dt.AsEnumerable()
                .GroupBy(x => x.Field<string>("Name"), y => y)
                .ToDictionary(x => x.Key, y => y.FirstOrDefault());

            Dictionary<string, List<DataRow>> dict2 = dt.AsEnumerable()
                .GroupBy(x => x.Field<string>("Name"), y => y)
                .ToDictionary(x => x.Key, y => y.ToList());
jdweng
  • 33,250
  • 2
  • 15
  • 20
  • Hey, thanks for replying. But you seem to have misunderstood what I'm trying to do. I have said that I ditched the DataTables and now I'm using a one-for-all-dictionary. I gave an example as a JSON of how the dictionary looks like, and how I want it to be as a DataGridView. When adding something new to the dictionary, I want to change the DataGridView real-time. – Rookie Apr 22 '19 at 12:10
  • Why ditch the DataTable which is more efficient then getting a JSON and then converting JSON to classes? You should always change the DataSource of the DGV instead of trying to modify the DGV directly. – jdweng Apr 22 '19 at 12:26
  • @Rookie If you want real-type updates, you need an object that can notify property changes. A `DataTable` can, so do both `BindingSource` and `BindingList`. You're best friend here, is probably a DataTable linked to a BindingSource. Btw, you **really** don't need a DataTable for each `var-type`, that's the DataRow content. You could add a Column (to the DataTable, hidden in the DGV) that acts as an identifier/indexer, if needed. – Jimi Apr 22 '19 at 12:28
  • ...I don't have a JSON, mate. I've said it a couple of times. It was only an example, the source is an `internal static Dictionary>>> Variables { get; set; }`, I'm not trying to modify the DGV directly. I just want it to update when my dictionary changes. – Rookie Apr 22 '19 at 12:28
  • @Jimi: I can still have multiple tab pages each with a different `var-type` with just one DataTable? – Rookie Apr 22 '19 at 12:32
  • If you bind different DGVs to the same BindingSource, all will be updated when something changes. You might have to play with the `CurrencyManager` sometimes, but that's it. Also, note that filtering a DataTable using a DataView, then using the DataView as the DataSource, the binding is still active and all updates work the same way. – Jimi Apr 22 '19 at 12:35
  • @Jimi: You said I don't need a different DataTable for each var-type, how so? Each var-type has its variables, and each variable must have Name - Description - Length - Type – Rookie Apr 22 '19 at 13:17
  • I'm looking at the structure you posted. A `"var-type"`, whatever that is in practice, it's an identifier. Thus a field that identifies the *owner* of a record. You're showing that the data in the DGV should be `flattened` (reduced to one record). It look quite straightforward to me. I don't see what problem you might have. I see a lot of problems coming from a nested Dictionary. Should you decide to actually use that data structure as a JSON (or like a JSON) and *deserializing* to a DataTable, all *problems* are gone. – Jimi Apr 22 '19 at 13:56
  • Are you saying you have you have a dictionary for multiple files and then a 2nd level dictionary for each type like "var-type" and then a third level dictionary of properties? You siad : Dictionary>>> Variables { get; set; } – jdweng Apr 22 '19 at 14:12
  • @Jimi: I think we both have a misunderstanding. Could you please provide an example of what you're talking about? All I want is to update a DGV that has a Dictionary as its DataSource when new keys get added to the dictionary. The "var-type" you're talking about is a tab page, inside that tab page is a DGV of that specific var-type. I can't have multiple var-types in one DataTable, it's not a dictionary. It's one DataTable per type, so I can do that table I posted. – Rookie Apr 22 '19 at 14:23
  • @jdweng: hey, yes. :) 4 levels of dictionary nested, all date in one dictionary. Just like that JSON I posted – Rookie Apr 22 '19 at 14:24
  • Do you want to update all 4 dictionaries or just one? – jdweng Apr 22 '19 at 14:31
  • @jdweng: only the last two levels. If you look at that JSON, I would like to update var1 and the JSON inside it. I can already do this, but would have to refresh the DGV manually. I want it to happen automatically. Just like when the DataSource is DataTable, it happens automatically – Rookie Apr 22 '19 at 14:34
  • You have to force the DGV to repaint. It doesn't automatically repaint. So the trick is to set the data source to null and then back to the table like : datagridview1.DataSource = null; datagridview1.DataSource = dt; – jdweng Apr 22 '19 at 14:47
  • @jdweng: how do i do that whenever the dictionary changes? the DGV is in a different form. Is DataTables really my best option here? – Rookie Apr 22 '19 at 15:08
  • You need to communicate to 2nd form with DGV using the instance of the form. Create a method in the form that sets DataSource to Null and then to table. See my two form project : https://stackoverflow.com/questions/34975508/reach-control-from-another-page-asp-net – jdweng Apr 22 '19 at 15:18
  • Hmm, okay, thanks. I think I'm going with what @Jimi said, and switch to DataTables. Thanks a lot for replying, @jdweng! – Rookie Apr 22 '19 at 16:02
  • If you have some DGV2 in different Forms, remember to use a BindingSource to bind the DataTables to the DGVs. This way, all the bound DGVs will be updated (real-time), even if you show a Form as modal `[Form].ShowDialog();`. – Jimi Apr 22 '19 at 16:10