user1181480
user1181480

Reputation: 1

Access windows by name

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

Answers (2)

Michael Edenfield
Michael Edenfield

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

GameAlchemist
GameAlchemist

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

Related Questions