Click here to Skip to main content
15,880,392 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hi. I am working on a project where I find myself wanting the view model objects to have a reference to its view object. Is this bad design?

If not, how would I make sure that this link is kept updated? Currently I added an event handler to the DataContextChanged event of the view. I also use DataTemplate tags on the following form for instantiating views:

XML
<DataTemplate DataType="{x:Type viewModels:ToolBoxViewModel}">
    <views:ToolBoxView />
</DataTemplate>


This means that the view will automatically be instantiated, but not before the view is actually needed for display!

Consider a tab view whose model contains a list of view models that are to be represented by an AvalonDockingManager view in each tab of the tab view. I want to be able to load and apply layout on all the tabs at program start-up. Of course, when I start the application, only the first tab is displayed. The view model of the first tab gets a reference to the view and the layout can be loaded. However, the second tab doesn't have a view yet since it hasn't been displayed. So I can't load the layout - the AvalonDockingManager has not been instantiated yet.

Should I instantiate my views manually to make sure they exist at start-up? What would be the best practice for this?
Posted
Comments
_Maxxx_ 6-Jan-14 21:08pm    
Just answering your first question - yes, having the VM have a reference to your View is bad practice, and I would recommend not doing it.
I don't know AvalonDockingManager so can't help more than this, sorry1
fre_ber 7-Jan-14 12:43pm    
I feared as much.

The thing is that the view, in this case the Avalon Docking Manager, holds a lot of state information that I need to be able to load and save. The "command" handlers for the load and save operations are in view model class of the main window - where else could they be?
_Maxxx_ 7-Jan-14 15:28pm    
You're right - and I think I see what you're trying to do, now.
I tend to use the Xaml code-behind for this sort of stuff (no - stop it, don't scream like that!)
So the code-behind calls a method on its VM (say SaveState()) that takes as parameters whatever is necessary(in your case maybe the docking manager and a key). The VM takes the parameters, and does what it needs to have them saved to some repository.
Then you also have a method LoadState() that would probably take the same parameters, but this time set the state of the docking manager.
This way, your VM only has to know about the Avalon State Manager object, and not a particular view.
some people squirm when they see me advising the use of code-behind, but that's what it's there for, IMHO, to do GUI work; and this is one of those cases where the boundaries between GUI and Business logic become blurred.
fre_ber 8-Jan-14 10:19am    
Thanks. I don't have any issues with using the code-behind of the views. At least not yet. I am an MVVM-noob. ;-)

I am using a serializer to store the layout state of these view objects - the main window and all the "workspace" views that it contains. Each "workspace" view has its own view model.

Would it be extremely bad to have the code-behind serialize it every time the layout is changed and make it send the serialized data to the view model for storage until it needs to be saved to a file?

Analogous to that - every time the view needs to lay itself out, it would first query the view model for the serialized data, deserialize it and then apply.

I haven't looked, but I am sure there are either events I can listen to or methods I can override to make this happen. I wonder if it will be overly "heavy" though.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900