I would like to ask if it's possible to somehow find and list all of the DataSets that are on a Form.
I could not find them in the Form Controls, they have been added via the Visual Studio form designer and there will be so many different DataSets in the software I am building that I want to write a library for their general management, but for that, I have to add them to a list somehow, and I can't find anything on this topic.
List<DataSet> formSets = new List<DataSet>();
//Operation to find all DataSets on the Form <--- This is what I'm looking for,
//probably a cycle which results in DataSet typed foundDataSet each time it executes.
formSets.Add(foundDataSet)
//Number of other initializing operations like setting defaults and so on.
The DataSets are strongly typed, but I only aim to perform generic DataSet operations on them, as the code already states.
Thank you in advance,
Gray / Gary H.
Well, after thinking a little I realize that instances of Dataset are not part of control collections, they are just members of the form class.
So, the idea is to load the containing assembly, get all Form's subclases and then find all their members who are dataset types or inherit from it. The following code should make it using reflection
using System;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;
namespace TypeFinder
{
class Program
{
static void Main(string[] args)
{
// args[0]: Assembly path, args[1] Assembly containing type to find, args[2] Type to find
Type typeToFind = LoadTypeFrom(args[1], args[2]);
var forms = Assembly.LoadFrom(args[0]).GetTypes().Where(t => t.IsSubclassOf(typeof(Form)));
foreach (Type form in forms)
{
var fields = form.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
foreach (FieldInfo fieldInfo in fields)
{
if (IsSubclassOrSameTypeAs(typeToFind, fieldInfo.FieldType))
{
Console.Out.WriteLine($"Found type {fieldInfo.FieldType} as IsSubclassOrSameTypeAs of {typeToFind}");
}
}
}
Console.Out.WriteLine("Press any key to exit...");
Console.ReadLine();
}
private static bool IsSubclassOrSameTypeAs(Type baseType, Type descendant)
{
return descendant.IsSubclassOf(baseType) || descendant == baseType;
}
private static Type LoadTypeFrom(string path, string type)
{
if (string.IsNullOrEmpty(path))
{
return Type.GetType(type, true, true);
}
var assembly = Assembly.LoadFrom(path);
return assembly.GetType(type, true, true);
}
}
}
You can call this program with an assembly path or a fully qualified type name:
"C:\MyCustomAssembly.dll" "C:\MyCustomAssemblyWithTypeToFind.dll" "MyNamespace.MyCustomType"
"C:\MyCustomAssembly.dll" "" "System.Data.DataSet, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
Hope this helps, kind regards.