1

I have a certain folder with a couple of view classes (XAML files). Right now i am instantiating these by code:

engineRoomView = new EngineRoomView()
{
   DataContext = new ProcessViewModel()
};

and then further down:

item = new TabItem();
item.Contents = engineRoomView;
item.Name = "Engine Room";
views.Add(item);

What I want to achieve is some kind of dynamic code for creating one instance of each view in that particular folder without knowing about them during programming.

If a developer adds another xaml file to that folder. Then this gets created in run-time.

Something imaginary like:

Foreach(file in folder)
{
   magicInstance = createInstanceFromFile(file);
   MainViewModel.addView(magicInstance);
}

Is this possible?

croxy
  • 4,082
  • 9
  • 28
  • 46
jsandv
  • 276
  • 4
  • 20
  • 1
    You can load a XAML file at runtime using XamlReader.Load(stream); you only need to create a stream to read the .xaml file – nkoniishvt Jan 07 '16 at 14:45
  • If the namespaces are consistent you could use reflection to find all the 'view' classes in the current namespace, iterate them, and add them to a list. – Bradley Uffner Jan 07 '16 at 14:58

2 Answers2

0

If I understand you correctly, this could be archived with the build in Xaml Reader. The Xaml Reader can read a xaml file and will generate the objects based on the xaml.

Have a look here: Loading XAML at runtime?

Community
  • 1
  • 1
unkreativ
  • 482
  • 2
  • 8
0

It sounds like you have a "Parent View" that you want to automatically attach a child view for each file in the same folder.

If the classes in each folder have a namespace consistent with the folder structure, this code should allow you to create a list of an instances of each class in the same folder as an example instance that inherit from a base class (could modify easily for interface also).

static class NamespaceHelper 
{
    public static List<Type> FindTypesInSameNamespaceAs(object instance)
    {
        string ns = instance.GetType().Namespace;
        Type instanceType = instance.GetType();
        List<Type> results = instance.GetType().Assembly.GetTypes().Where(tt => tt.Namespace == ns &&
                                                                          tt != instanceType).ToList();
        return results;
    }

    public static List<T> InstantiateTypesInSameNamespaceAs<T>(object instance)
    {
        List<T> instances = new List<T>();

        foreach (Type t in FindTypesInSameNamespaceAs(instance))
        {
            if (t.IsSubclassOf(typeof(T)))
            {
                T i =(T) Activator.CreateInstance(t);
                instances.Add(i);
            }
        }

        return instances;
    }
}

Just call NamespaceHelper.InstantiateTypesInSameNamespaceAs<YourBaseViewType>(instanceOfParentViewInSameFolder), loop through the results, and add them to your Parent.

Foreach(ViewBase v in NamespaceHelper.InstantiateTypesInSameNamespaceAs<ViewBase>(this))
{
   MainViewModel.addView(v);
}
Bradley Uffner
  • 16,641
  • 3
  • 39
  • 76
  • Yes, it seems like you understanding is correct. So hopefully the example you provided will solve this for me. Thanks! – jsandv Jan 07 '16 at 19:45