1

here's the problem: In my WPF application I used to load/parse my .xaml files using XamlReader.Load Method to open a window in my application.

Codefragment of my function which return the window:

Dim win As New Window()
Dim myObject As Object

Dim xml As XmlReader = XmlReader.Create("mysample.xaml")
myObject = System.Windows.Markup.XamlReader.Load(xml)
win = CType(myObject, Window)
Return win

I use this to display all my different windows the user wants to see.

I open the window with win.Show and close it, when user switch to another window with win.Close. It works well!

Now to increase the performance I plan to do all the XAMLReader.Load at Application Start and store the information into a Dictionary:

Private Shared windict As Dictionary(Of String, Object)

Public Shared Sub ConvertXAMLToWindow(ByVal formName As String)
      windict = New Dictionary(Of String, Object)
      Dim myObject As Object
      Dim xml As XmlReader = XmlReader.Create(formName)
      myObject = System.Windows.Markup.XamlReader.Load(xml)
      windict.Add(formName, myObject)
End Sub

Then I want to use that information when calling windows:

If windict.ContainsKey(formName) Then
 Dim win As New Window()
 Dim myObject As Object

 myObject = windict(formName)
 win = CType(myObject, Window)
 Return win
End If

Now This works well, but when I use win.Close to close my window I get an error when trying to open it again with win.Show, although I create an new instance of Window?

System.InvalidOperationException Cannot set Visibility or call Show, ShowDialog... after a Window has closed.

But it works when I don't use the Dictionary Method but the XAMLReader.Load directly - any ideas whats going on ? Somehow the window I get by returning XamlReader.Load seems different than the stored information from the dict?? Am I missing somehting? Thanks in advance!

PeteH
  • 13
  • 3
  • Once the window is closed, you cannot use it again. You need to create a *new* instance of the class. Shoots a pretty big hole in your approach. – Hans Passant Aug 22 '12 at 12:27

1 Answers1

1

You could use Hide() instead of Close()

Hide hides the Form, so instead of disposing of the form (and its controls) you make it invisible. Show will make it visible again.

Be careful though, the form in the dictionary will still hold the state from the previous time it was used.

Emond
  • 50,210
  • 11
  • 84
  • 115
  • Thanks for the answers. I think I will use Hide() as you suggested - I still wonder though why it works with XamlReader.Load but not with dictionary. Anyway thanks! – PeteH Aug 22 '12 at 15:52
  • XamlReader.Load creates a new instance opposed to storing the instance in the dictionary. – Emond Aug 22 '12 at 19:00
  • That makes sense! Thanks Erno! I guess this means that I don't have any chance to use win.Show - win.Close mechanism without using XAMLReader everytime I want to show a window? Well I think I will use Hide instead in conjunction with the windict - seems to be the best solution for me :) – PeteH Aug 22 '12 at 20:14
  • A quick thought: what if you use XamlReader once, call GetType() on the Window you've just created and store the Type you get in the dictionary. From then on To create an instance you then can use Activator.CreateInstance to create a window and use Show and Close. – Emond Aug 23 '12 at 04:11
  • Very good idea sounds perfect! I will give it a try and report result, thanks! – PeteH Aug 23 '12 at 14:22
  • So you mean storing only the System.Type (=Window) in the dictionary? But when I do this, I will loose my window informations? I tried it it and then it return a blank window every time which seems logical to me. – PeteH Aug 23 '12 at 15:05
  • Yes, but that is what Close will always do. If you want to keep state put the instance in the Dictionary too. Dictionary> string = name of the type, Type is created by XamlReader/GetType, Object by Activator.Create instance. Now you can chose to create a new instance or get the existing instance. – Emond Aug 23 '12 at 15:13
  • Sorry for late response, though I decided to go the Show/Hide way - it works well in my case. Thanks for help and interesting contributions though! – PeteH Aug 27 '12 at 08:05