MVVM and binding to IsOpen?

Docking/MDI for WPF Forum

Posted 6 years ago by Ulf Johansen
Version: 14.1.0601
Avatar

I have an observable collection of documents bound to DockSite.DocumentItemsSource but when the user closes a document i want to get rid of it completely. The user can close the document either by clicking a menu item that executes a command on the viewmodel or through the close button on the document window.

I tried to add a IsOpen property on my document viewmodel and bind that to IsOpen and then remove the document from the collection when notified with IsOpen == false, which I defer using Dispatcher.BeginInvoke, since I cannot change the collection that is bound on the raised property change event.

The problem is that the IsOpen dependency property is changed when the layout is updated (I.e. docking a window, etc.) and in addition to not really being what I want it also crashes the application in random ways, sometimes with null pointer exceptions and sometimes with WPF exceptions complaining that the logical tree is updated during a traversal (but not with any of my code in the callstacks so seems somehow the internal state gets corrupted). As an sidenote, I also tried to bind in a similar way with tool windows and in that case I never receive a change for IsOpen when the window is closed, so this is also not working just in a different way.

So I'm thinking that I'm not really suppose to bind to IsOpen in this way but then how am I suppose to manage my viewmodel? I can hook the events and I'm assuming (still haven't tested this) that at least these will not fire when the layout is changed because if they are I'm a bit unsure how I detect whether they are fired as a result of the user pressing a button or whether it is because of a layout change

But even if this is working, it is all really awkward in terms of MVVM, so I'm wondering if I'm missing something?

Regards

Ulf

Comments (3)

Posted 6 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Ulf,

Can you make a new simple sample project that shows the issues you are running into and email that to our support address so we can debug it and see what's going on?  Please rename the .zip file extension of what you send so it doesn't get spam blocked.  You should be able to bind to IsOpen successfully as I believe we have other customers using that concept for determining whether various docking windows are open.


Actipro Software Support

Posted 5 years ago by Jay Hill
Avatar

Were there any findings as a result of this exercise? I've had some of these same problems binding to IsOpen as well, in particular when using layout deserialization. The deserialization process seems to overwrite any bindings declared on IsOpen.

As a workaround, I am creating bindings in code-behind after the layout has been deserialized, but I am curious whether any guidlines could be gleaned from Ulf's sample project (assuming he submitted one).

Posted 5 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Jay,

Yes, the problem in Ulf's sample at least was that you can't really assume that the DataContext is going to flow down in a DockSite hierarchy since as docking windows move around, their DataContexts change. You need to explicitly set the DataContext on each docking window like:

DataContext="{StaticResource MainViewModel}"

or at least make your binding reference something like the Window's DataContext directly:

IsOpen="{Binding Path=DataContext.IsToolWindow1Open, ElementName=window, Mode=TwoWay}"

There are other possibilities but basically if you make sure the DataContext is set directly to the docking window, you won't have problems with bindings as docking layouts change.


Actipro Software Support

The latest build of this product (v2019.1 build 0683) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.