|
Using a template like below might help you out.
<toolkit:Expander x:Name="ExpanderControl" ExpandDirection="Down" IsExpanded="True" >
<toolkit:Expander.HeaderTemplate>
<DataTemplate>
<UserControl myContrl />
</DataTemplate>
</toolkit:Expander.HeaderTemplate>
</toolkit:Expander>
|
|
|
|
|
A coworker and I were discussion the design for a WPF app. It's being built using MVVM.
We have a series of user control that are going to be added to the main window at runtime. The user controls to be added are determined by the data coming back from the repository. So for model A, add user control A, type B, add user control B, and so on. The main window's VM would call into the repository, get back a collection of models, and then for each mode, determine which user control to add to the grid in the main window.
He was adamant that the VM "should not know anything about views because this breaks the MVVM pattern." He insisted that you can do all this through data templates. he also suggested that I read up on MVVM and I'll see this is true. Now I'v read lots of MVVM artiicles and Josh Smith's book, and blogs galore. I have never hear this notion that the VM can't know about views (add views at runtime).
If you're going to add controls at runtime, then the main window VM is going to need to know about the views. I am working on another WPF app that has a toolbox and design surface (canvas). The user will be able to drag & drop controls off the toolbox onto the design surface. I don't see how this could be templated, and I'm pretty sure that there's no way to do this without the main window VM adding the controls to the main window view.
I'm open to opinions. Documentation would be good.
Everything makes sense in someone's mind
|
|
|
|
|
Opinion only I'm afraid, I'm not as well read as you but from what I can glean he is right although I am wary of being adamant, I prefer a little flexibility.
I would think you would have place holders of some description in the view that are bound back to a set of properties in the VM, the VM sets the properties according to the suppository.
I have gone as far as having all the controls in the view and just fiddling with the visibility of the container element. Note this is always limited to 2 or 3 controls.
How you would do this with templates I do not know.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
Yes good point.
Visibility, can however, be controlled via binding.
Other items like collapsing an Accordion just do not work using binding and I have not found a decent way to implement this without accessing view controls in the view model.
|
|
|
|
|
|
This all assumes that you know the controls ahead of time. If the controls being added are determined by the user, then there is no way to do this without the VM adding views.
Everything makes sense in someone's mind
|
|
|
|
|
More to the point it would only be really viable if there are very limited number of controls so the assumptions would kill this idea.
Never underestimate the power of human stupidity
RAH
|
|
|
|
|
From a purist's perspective, yes, a view model should not know absolutely anything about the view.
Think of this from a unit testing perspective - if you are going to write some tests for your view model and you have reference to the 'view' in that, its going to be that much harder to get around the view and write a test case.
However, I've noticed that while implementing run-time animations etc, I have sometimes failed to have view 'independent' view models.
Very often, I just use the Tree Helper and parse through view controls from within my view model - not the best implementation from the purist perspective. But with animation and 'hey whatever works' in mind, sometimes a deviation from the pattern works better.
|
|
|
|
|
I have heard it said WPF was designed with MVVM in mind.
Anyone know if this is true? Any documentation to support this?
Thanks
Everything makes sense in someone's mind
|
|
|
|
|
That's not quite right. MVVM was invented by John Gossman to support WPF development, because WPF provided far superior binding capabilities to its predecessors. It's often said that WPF was designed with MVVM in mind, but that is not the case - in fact, John had been working on Avalon for three years before he publicly coined the term Model View ViewModel[^].
|
|
|
|
|
Although, the answer does very much depend on what you understand MVVM to mean. The underlying 'essence' of the pattern is rooted in the Presentation Model pattern which Martin Fowler described before the WPF framework was developed.
http://martinfowler.com/eaaDev/PresentationModel.html[^]
This is something that Gossman openly acknowledges. In my opinion, MVVM is a WPF / Silverlight specific implementation of the Presentation Model, in that the general understanding is that you set your view-model as the DataContext of the view, minimise code-behind and promote design-time data and unit testing. WPF was designed with these concepts very much in mind.
|
|
|
|
|
Ahh, time for the Disciples to go forth bringing knowledge to the masses.
Indeed, MVVM derives from the Model View Presenter, but it is closely tied to Model View Passive Presenter which Fowler came up with at roughly the same time as John. It was a logical extension of MVP, so there's no real suspicion about the relatively simultaneous independent creation of logically related concepts.
|
|
|
|
|
Indeed. What Pete said! It's all MV-Poo
However, I do get very annoyed when people take the conceptually simple and elegant MVVM pattern and extend it into something that is much harder to comprehend. Does anyone really need the Model-View-Presenter-ViewModel (MVPVM) pattern?
http://msdn.microsoft.com/en-us/magazine/hh580734.aspx[^]
Admittedly, I haven;t read the article - so maybe I am a bit hasty in judging. However, what I really like about MVVM is that I can explain it to any competent developer within about 5 mins and know that they will follow it correctly. The same cannot be said for 'classic' MVC pattern.
|
|
|
|
|
Indeed, you're right. MVVM is a simple concept - granted there are subtleties, but these are implementation subtleties and nothing to do with the underlying pattern. What annoys me is when people heap all sorts of different patterns on top and then say, "this is MVVM".
For instance, although we all use Mediators or Messengers, they are nothing to do with MVVM - they are merely a way to help communicate between separated concerns. Similarly, when people say that MVVM is DI or IoC, again, these are just other techniques to help - they aren't MVVM. Properly applied, they help make better code, but they are not part of the core MVVM concept.
Possibly my biggest bugbear is when people think that MVVM means that you have to remove ALL code behind. That's just plain errant nonsense. If you want to trigger an animation just because your window is closing then, by all means, trigger it from code behind.
Ah well, we're just rehashing old ground here.
|
|
|
|
|
|
I don't like it. Messages are getting lost this way.
|
|
|
|
|
Pete O'Hanlon wrote: Possibly my biggest bugbear is when people think that MVVM means that you have
to remove ALL code behind. That's just plain errant nonsense. If you want to
trigger an animation just because your window is closing then, by all means,
trigger it from code behind.
I know this was just an example, but this is definitely something that can be done entirely in XAML. I'm one of those guys that self enforce the no code-behind rule . So far, I haven't found a need to have code behind. There are plenty of MVVM tricks to get around the need... if you are writing a lot of code behind, you should probably repackage it in a nice MVVM friendly UserControl or something of that sort.
If you start allowing code behind, it gets hard to draw the line... you end up with a lot of "I was feeling lazy that day, so I'm going to throw it in the code behind and move it later" -- which never happens.
Plus, you end up with your logic split across two .cs files 
|
|
|
|
|
You're right, there are lots of MVVM tricks that can be used to remove all the code behind. But at what point does it become too much? Each additional thing you put in place becomes yet something between you wanting to do something and actually doing it, and each bit takes that bit extra time. I am all in favour of removing unnecessary code behind, but when it becomes dogmatic then you have gone too far.
|
|
|
|
|
No this is not true (as per wiki[^]).
"MVVM was designed to make use of specific functions in WPF to better facilitate the separation of View layer development from the rest of the pattern by removing virtually all “code-behind” from the View layer."
|
|
|
|
|
A few years ago, I wrote a native WPF task dialog. It has served me wonderfully for years. It looks exactly like the standard Windows task dialog, but allows me to re-template certain areas. I've never actually had to use the custom re-templating until now, so I never really thought about this issue...
Cliffs:
* the task dialog is essentially a UserControl
* it's written all "WPF-y"... to re-template the content section, I would do:
td.ContentTemplate = (DataTemplate)Application.Current.FindResource("InputPromptTemplate");
for example.
That part all works fine. The custom template works as intended. The question is, I never really thought of a way to allow data binding in that template. The data context is going to be set to the task dialog's data context obviously, not my VM. So If I was to do something like:
<CheckBox IsChecked="{Binding MyCustomCheckBox}" />
It would obviously expect MyCustomCheckBox to be a part of the TaskDialog class and it isn't. The TaskDialog is a pop up dialog, so I can't chase up the VisualTree from XAML either.
Any ideas how to set this up? It isn't really MVVM actually, just using the TaskDialog straight up in this manner would have the same issue.
|
|
|
|
|
Hi guys,
I have to create a control similar with the one from browsers -> on editing a listbox appear with the history.
The problem is I don't know exactly how to "anchor", the listbox control under the text box cotrol; or what to use.
I have a groupbox with a grid, inside my textbox. I create dynamicaly the ListBox inside the parrent element but I don't know how to display it under the textbox.
george
|
|
|
|
|
Use a StackPanel control and place the textbox above the ListBox.
For example,
<StackPanel>
<TextBox/>
<ListBox>
<DataTemplate/>
</ListBox>
</StackPanel>
|
|
|
|
|
I did not tried but there are 2 problems.
1. I guess if I used like this ...the listbox will be drawed inside my groupbox and grid.
I want to be displayed just under the textbox and drawed, over , outside the groupbox, grid.
Is it possible?
2. What if I want to have something like the autocompletion menu from Visual Studio 2010 and want to display a listbox at a specific position inside the control.
|
|
|
|
|
Though I'm not able to visualize the exact UI you require, with Silverlight, you should be able to do this via templating and styling.
|
|
|
|
|
The control in the browser where you enter a URL? Thats a ComboBox, not a TextBox with an anchored ListBox. Just set the style on the ComboBox so that it is editable.
|
|
|
|