How can one change the height of the container view dynamically depending on the amount of images of its childView?
It's a view like any other view, so you change it in the same way. You'll need to arrange to get a reference to it. When you set things up in the storyboard like this, you get an extra level of hierarchy that you wouldn't get if you created the parent-child view-controller architecture by hand (in code): there is a container view and inside that is the child view controller's view, whereas if you do it in code, there is no container view - the child view controller's view is all there is.
Related
Im currently learning about the MVVM pattern in WPF. I think it is really cool but my question is: is it correct to use the viewmodel directly for appending children to its view?
For example lets assume we had a method which contains a loop which adds new rows to a grid when a button is clicked. Should my ViewModel only contain pure data or can it also contain logic for placing new elements on the field? As well as removing them.
is it correct to use the viewmodel directly for appending children to its view?
No. The view model shouldn't know about any view elements.
Should my ViewModel only contain pure data or can it also contain logic for placing new elements on the field? As well as removing them.
The former. The view model may expose a collection of data objects that the view happens to display in a Grid. Or some other kind of panel. The view model doesn't care about which.
You would typically use an ItemsControl in the view to display the items in a view model collection, i.e. the ItemsControl binds to the source collection and displays a visual representation of each item in a panel.
I have a requirement to display a number of graph/chart "thumbnails". Clicking one will show an "expanded view" (in a separate panel) that displays a larger version of the chart, plus controls to view and manipulate the chart.
There will be a number of different charts, each plotting my data in different ways. Also, a given chart type may appear several times, each plotting a different subset of the data. The controls in the "expanded" view will also differ from one chart type to the next, so there is little commonality here.
I'm struggling to get my head around how to model all this in MVVM, especially given the need to dynamically create an unknown number of thumbnails (and in some cases multiple instances of the same type).
Thinking aloud, I guess I need a view/viewmodel that represents a single thumbnail (the view contains the chart component and the VM exposes the data to plot). I guess I also need a V/VM for the "thumbnail list" UI, responsible for creating the thumbnails and exposing them via a collection for binding to the list. But how does it instantiate these? A VM gets injected into its view, suggesting the "thumbnail list" VM would have to dynamically instantiate the thumbnail views - but a VM shouldn't have knowledge of views should it?!
Lastly, when I display the "expanded" view, it would make sense to (somehow) pass it the charting component/view that was used in the thumbnail, to avoid having to render the chart again, but how?
If it's relevant/helps, I'm using Castle Windsor for dependency injection, and the navigation features of Prism.
This is indeed a complex topic,...
I would suggest a VM for the list of icons not necessarily for the icon itself. this can be bound to properities of the IconListViewModels. Then you should think about a ChartViewModelFactory. Which works in conjunction with your DIC.
An important discussion is the VM-V marriage. View first or View Model first... one way could also be ViewResolver if which returns the matching view based on your view model... this can rely on some sort of conventions. So the final steps could be ask the factory for a view model find the matching view glue them together and bind them to a content presenter...
I hope this helps to get you started...
I'm starting on my first WPF project using MVVM and Castle Windsor. I'm following the fairly standard approach of injecting a view model into its view's constructor, which then sets its DataContext to the view model. What I'm not clear on is how/where to perform any UI "initialisation" that I want to happen right after the window has loaded (in my case I want to instantiate a number of user control "widgets" and put them on the window's canvas).
Presumably I can't do this in the constructor of the window's view model, as it will have been called prior to the view's InitialiseComponent being called. Besides, how would I even reference the canvas from the view model, which should have no knowledge of the view?
As part of trying to solve this, I created a "DesktopManager" component responsible for adding user controls to the canvas, but I'm getting circular references:-
the view obviously has a dependency on the view model
the DesktopManager has a dependency on the view (it needs to access the Canvas),
the view model has a dependency on the DesktopManager (so it can tell the DesktopManager to create the widgets).
The DesktopManager still won't help me though - referring back to my earlier question I don't know how/where to call it to create the widgets. I'm clearly going about all this the wrong way, and perhaps answering my earlier question will solve this one too!
Any suggestions appreciated.
Andrew
If you are looking for a way to execute code in your view model once the view has been loaded, I would suggest that you bind the Loaded event of the view to a command in your view model.
Look here for one way to bind events to commands:
http://www.danharman.net/2011/08/05/binding-wpf-events-to-mvvm-viewmodel-commands/
I have an application that has a view area. In the view area contains a grid that will contain a collection of controls, such as images, list views, data grids and text.
One one view will be visible at a time, since there is only one view area. Currently when the action is performed to make a new view active I render the view and set it as a child to the view area. Some views takes up to a couple of second to render, so there is a latency here.
I would like to render all 10 views when the application is first loaded and then just grab the appropriate view when called upon. I have not been able to do this. A lot of my view items are usign proportional sizes, the grid uses the Star for the row and column sizes, so it appears that until the view is bound to a visable area where it can calculate all of its sizing it doesn't actual perform any rendering.
For instance, my data grids still flick as it opens it with all of the columns set to 20 width and then it snaps them to the correct widths after. You can visually notice this on the screen, an intial draw with narrow columns and then they all expand to fill the data grid area.
I want to do all rending in the background, then once it is finished display the final product.
A control cannot perform final rendering until it has a container. Maybe try hosting the views differently. Maybe build your views as pages and host the pages in a frame. I don't guarantee that will be faster but something to look at. Could you use tab? I am pretty sure a tabitem reuses the last rendering or at least pieces of the last rendering. Optimize your individual views. A GridView is typically faster than a DataGrid but may not have the features you need. For a table where I need speed I use a GridView and set the column widths based on the data - 100 rows and 40 columns renders in than 1.0 seconds and I put it in a tabitem and if I come back to the tab (after it has rendered once) it renders in 0.1 seconds. If a view has a lot of data that scrolls then try virtualization. Or load multiple frames in the same column / row and only have one visible at at time.
You could try having a separate view area that is the same size as the main one but that is hidden behind the main one, and put all of your 10 views as children of that one so that they render with the appropriate sizes, then swap them out into the main one as necessary...
I've noticed a problem I'm having depending on the Hierarchy of items. When I wan't to represent the items I have no idea how to put it's children in a manageable state.
Let's take a TreeView for example. When the window is loaded up I can take the model and put it into a view and as a source for the tree. However I seem to have no real control over the children. Only thing I can do is point to the children property of object and it shows up all real nice but what if I wan't to edit, sort and/or add a new item there I'm out of luck.
I can't really put the children into the view or a seperate collection to modify as they are only the property of the root element. Only way I can see at the moment is having the property return a ObservableCollection or a CollectionView and that has it's own problems as in no lazy loading for example.
How are you doing this, what is the proper way here and what am I missing?