Reputation: 1
I am quite new to WPF, coming from the Delphi world. I solved the problem below (albeit painfully) in the Delphi world, and hope there is a more elegant solution in the WPF world.
I need to read in an XML file containing a menu "tree", which has the window names in it as well as the menu prompts, and then be able to "show" a window based on having its name.
For example, a segment of the menu, with two choices, might have XML like this:
<MenuLeaf>
<Header>Product information</Header>
<MenuLine>
<Prompt>Product Master File</Prompt>
<WindowName>Products.xaml</WindowName>
</MenuLine>
<MenuLine>
<Prompt>Inventory Data</Prompt>
<WindowName>Inventory.xaml</WindowName>
</MenuLine>
</MenuLeaf>
So when the user makes the "Inventory Data" choice, I will know that I want to do a "show" of the window Inventory.xaml ..... but I only have the literal string "Inventory.xaml".
I will have hundreds of these forms, and the XML file can vary from time to time - so it's not effective for me to have the standard code of
Dim window as New Inventory
window.Show
for each of the several hundred windows.
What I need is something that does
Dim window as New {go out and find the Inventory file with name Inventory.xaml}
window.Show
I have searched endlessly for this with no luck.
Upvotes: 0
Views: 115
Reputation: 28338
You need to use the XamlReader object, which parses XAML at run-time and creates the object.
var rdr = XmlReader.Create(File.Open("Inventory.xaml"));
var window = XamlReader.Load(rdr) as Window;
window.Show();
The XamlReader.Load
will return whatever the actual top-level element in the XAML specifies; if it's a Window
you can just .Show
it. If it's something else, you'll need a container to place it in. For example, you might have a Window
with a Border
element in it and do:
var control = XamlReader.Load(rdr) as UserControl;
var window = new MyHostWindow();
window.ContentBorder.Child = control;
If you don't actually know the type of element in your XAML you can usually use FrameworkElement
, which is the base class for all the visual elements, though you won't get Window-specific behavior from that.
Upvotes: 0
Reputation: 19294
I think the path to solution is to use Reflection, which will allow you to dynamically find/invoke your classes. Say your Namespace is MyNs, then you must have a 'Products' Class within it that correspond to the 'Products.xaml' file. To find it, use MyFoundType = MyNs.GetType("Products")
Then get default (or other if you like) constructor for this type : MyFoundType.GetConstructor(). Then invoke the constructor (with arguments if needed) --> you now have your window as an Object.
Cast it to a window and call its Show method, and you're done.
http://msdn.microsoft.com/en-us/library/y0cd10tb.aspx
http://msdn.microsoft.com/en-us/library/h93ya84h.aspx
http://msdn.microsoft.com/en-us/library/6ycw1y17.aspx
Upvotes: 1