I want to create two diffent types of DockPanels. If the user clicks on one link, it loads DockPanel #1 otherwise it loads #2.
Can we dynamically swap them? I'm new to WPF. In REALBasic, I'd use GroupPanels and I'd swap them if needed.
Thanks
U can dynamicly create controls and fill their content with other controls. Or u can just place both types and hide one u dont want to show.
Take a look at Josh Smith's MVVM Article in MSDN Magazine. Josh is considered by many to be The MVVM Guru, and this article does a good job at explaining the basics.
With that in mind, I would probably do your app as an MVVM application.
The Model would "just" be your data model (much like in MVC).
Next there would be a View for each of your panels. Each View could either be set up as a DataTemplate (like in the article), or as a UserControl (as I've done and seen done many other places as well). Doing so makes it modular, and easier to expand, maintain, etc.
Your MainWindow is really also considered a View, onto which you place other Views.
All of the Views will be controlled by one or more ViewModel classes. How many you have depends on your design. Generally, if there is distinct functionality, you will have a more-or-less one-to-one relationship between a View and a ViewModel (although you can certainly share multiple Views with a single ViewModel). There will also generally be a single "Main ViewModel" class to hold everything together.
In general terms given the general description of your problem, it is likely that your ViewModel will contain a Command (or Commands), handled when your user chooses a link. This Command will likely set some property, which will control which View gets shown (usually via Binding).
Sorry I can't get more detailed than this, but if I did I'd need to know more about your design, and I'd have to write a lot more stuff, which isn't really appropriate in this forum.
Related
I'm working on a WPF project using the MVVM pattern and I was wondering if I can improve the internal structure of my ViewModel by abstracting its exposed properties into separate classes.
It's common practice for VMs to contain lots of properties laying around in the same class: Some are used to retrieved user inputs, some are used to expose commands, others to expose the models, and probably some other properties for the view model's own business logic. Not to mention that these properties often have set and get bodies that adds some bulk to the package. This can quickly become messy inside a VM class and finding one's way there can become challenging.
As a way to solve this issue, I am exploring with my team the idea of grouping properties inside my VM into different categories. As a first approach, I chose to group them this way:
ViewData, UserInputs and Commands, each one represented by its own class. Then I referenced them as properties inside my VM class.
My intention is that these classes will only act as placeholders to free up the bloat in my VM and keep it clean and focused only on interaction logic for handling user events.
It's a simple refactoring, but I get the following pros:
Cleaner and readable VM.
Easier binding from the XAML because you know what the entry point is/should be.
Let me elaborate on the latter one: If I want to bind a text box to a property of my VM, I know the binding expression should start with Userinput.MyVMProperty. If I need to show a value from my VM, I know my binding's entry point is going to be ViewData.MyOtherVMProperty. Binding intellisense will also become better because when you know your entry point, the
suggestion list would be smaller and more focused. This also works the other way around: when reading through your XAML controls, any binding that starts with UserInput necessarily means it's a a control that should send data back to the VM.
The only cons I can find is that this will require creating extra classes for each VM, but I believe it's a fair price to pay for the benefits you get.
Take note that the grouping I suggested may not be the best, but I don't mind any other grouping as long as it solves the problem with bulky VMs.
So, has any one ever tried a similar pattern? Do you think this is a good idea/practice? What other good practices I can use to improve my VMs?
Bonus question: One developer in my team who seemed to agree with this idea, suggested to go the extra mile and consider the grouped classes as VM dependencies and that they need to be injected inside the VM. What do you think about this?
So for every ViewModel you need to create own inner classes for every group. You cannot use Interfaces because ViewModels have different properties and commands
Then did you considered that every "groupclass" must to "know" about other groups for ViewModel will work properly.
In my opinion Class should be solid logical structure with minimal outside dependency.
Based on the pros you trying to achieve I can suggest another approach without changing structure of the ViewModel classes
Readability can be achieved partly by #regions.
Or use Partial class for separating different groups in the different files,
while keeping them inside one logical structure
Intellisense can be improved by naming conveniences - using prefix based on group property belong to. For example UserInputMyName, ViewDataFullName or CommandDelete
I try to avoid code behind in views, within my WPF MVVM project.
However I have some things that are very specific to the view. For example when a control gets focus I want the full text to be highlighted (even if a user clicks into the text box).
Here I have a choice to handle this in the view model (which would then need to know about the view, which I want to avoid).
I also have some other code like that does things to the UI when the user presses up down left or right on the keyboard (and they only make changes to the view, not the model or viewmodel) and again I'm thinking the best place for these is in the code behind of the view.
So I'm asking if the code only affects the view (e.g. things like cursor movement, selecting all text in a text box etc..., and not the model or view model, is it okay to put it in code behind, rather than elsewhere.
Wondering what is best practise here, or if anyone else has a better suggestion where to put this code.
So I'm asking if the code only affects the view (e.g. things like
cursor movement, selecting all text in a text box etc..., and not the
model or view model, is it okay to put it in code behind, rather than
elsewhere.
Not only it is OK, but it is strongly encouraged.
MVVM is not here for you to write thousands of ugly lines of code in ViewModels, it's here to make the code testable and to introduce a separation of concerns.
If it's purely related to the view (your "focus" example is a perfect example), then just write it in the code behind.
If the behavior is UI related only, then you should not put it in the ViewModel. The highlighting example you gave is a good example of such a case. Having said that, I would suggest you avoid repeating your code by (for example) creating a custom control that highlights the text when it has the focus. This way, you can reuse the control in as many views as you can, your views stay free of codebehind, and if you optimize your control, the optimizations happen across the board.
EDIT:
In light of Ravi's answer, Behaviors are also a way to introduce UI related logic while leaving the View free of codebehind. However, if you are finding yourself repeatedly declaring the same controls with the same behaviors, in my opinion it is better to create a control that incorporates the behavior.
That being said, if said UI logic is going to appear only once in one view, you may consider putting it in codebehind. Although it is quite rare to know in advance that you are not going to need that logic elsewhere.
EDIT:
I think #ken2k 's use of strong encouragement refers to not putting it in the ViewModel, which I also advocate. UI logic should be implemented in the View, as he says. Now, there are a few ways of doing that. One of these is coding it directly in your codebehind, which can lead to repetitious code and maintenance issues. Also, if you employ unit testing, it could put you in a difficult spot. The second is coding such logic into behaviors, which is a good way to encapsulate UI code. You can then unit test the behavior to make sure it works OK. However, you can find (as I did, in many projects) that you have started to pepper every TextBox in your XAML's with behavior tags. If that starts to happen, I would (and have) create a 'HighlightedTextBox' control and use that in my XAML. In summary, my suggestion does not contradict ken2k's, but is a pointer in the direction of resolving some issues you may have when placing logic for your View.
Using Custom controls as #Boluc Papuccuoglu suggested, is good option but before using that i want you to take look here Behaviors in WPF introduction
It is strongly recommended to have all your view stuff logic at one place. Instead of polluting ViewModel you should always keep View stuffs in XAML and code behind.
ViewModel responsibility is to contain only data part which can be unit tested. With UI stuff in ViewModel, you will make it hard to be unit tested.
As per link here at MSDN, definition of code behind:
Code-behind is a term used to describe the code that is joined with
markup-defined objects, when a XAML page is markup-compiled.
As you can see, code behind is partial class of your view. One half is declared via x:Class attribute at root element and other half in form of code behind. So, as per me all UI stuff should be at one place and you should not think twice before placing the view stuff in code behind. (that's what it is meant for). MVVM never meant design without any code behind.
Also ViewModel responsibility is to just provide data to your view via data binding. It should never be aware of UI stuff.
Read more about it here - Code behind and XAML in WPF.
How much of your code do you want to unit test? If your view can trigger a command when a control gets focus and your view model can programatically fire an event to highlight the text in that control then you have everything you need to unit test that behaviour with mocked objects. And even if you don't want to unit test (or can't because the bean-counters at your company won't give you the time/budget to do so) then placing that functionality in attached behaviours means they can be used elsewhere. I'm not quite the hard-core MVVM purist as some others on this site but I can honestly say that even in the largest enterprise applications I've worked on I've never once seen a case where WPF code-behind was absolutely required.
Recently i got explained that MVVM can only be done "the right way" if i use DataTemplates. Is this truely the case?
I'd say its a good idea to use DataTemplates if you want highly reusable "Views".
But if i am going to develop an application that has, say, five to ten different pages, and there is very little to none reuse of specific controls (like the "Person" view is only used once, and its highly likely that this requirement doenst change), why cant i simply create a usercontrol and put that directly into the code?
Am i missing some important core principle of MVVM here?
Main selling point of MVVM is separation of View from the ViewModel (so that VM doesnt know about View) by using powerful Binding feature of WPF.
DataTemplates are a just another feature which allows you to represent data in different way. As you have said, if you dont have reusable DataTemplate then dont create one, even if you do make sure it resides in the View's Resources, you can share it wider group if you wanted do.
using UserControl can be useful where you need to do something extra (apart from simple representing data), for example, some complex validation or extra commands/buttons
I dont think MVVM and DataTemplates are related in the same context.
There is no special needing for DataTemplate, you have a view and a viewmodel that cooperates with databindings and events. The MVVM goal in WPF is to remove the code from the view to achieve a real presentation only view, and not a messy code behind store. Having the ViewModel agnostic from the view is another goal, even if not always achieved.
We've been using the MVP pattern and Winforms with a fair amount of success. However, a question always pops-up about MVP:
What is a good granularity for presenters?
What I mean by that is: With Winforms, a fine-granularity usually works quite well for user controls. That way, it's easy to reuse user controls and use them as building blocks while designing more complex GUIs. However, having the same (fine-)granularity with presenters seems to be a problem.
On one hand, having coarse-grained presenters hinders the ability to use "plug-in" controls and it sorts of violate the DRY principle: Multiple presenters often need to implement the same logic (populate a list of customers, for instance), which is used by multiple, more complex, controls.
On the other hand, fine-grained presenters seem to limit the ability to reuse controls in different situations. For instance, an editing view might sometimes need to save the customer right away; sometimes it needs to link it to something else; sometimes is just needs to validate it; and so on. It often depends on the more complex control. But there's also a fair amount of shared behaviour.
Note that, in both cases, 1-presenter-1-view is achievable. What is considered "1-view" changes.
What is usually considered best-practices for presenter granularity using MVP and Winforms?
Fine-grained presenters and customizable behaviour through options or something of that nature?
Coarse-grained presenters and low presenter reusability?
Something else?
Disclaimer: We mainly use Supervising Controller but I think it also applies to Passive View. Sorry for the long question, too.
We use MVP at all of our clients and this is definitely a conversation that comes up in more than one occasion. How clean should our code behind classes and presenters be? Having said that, we have chosen to use the coarse-grained presenter approach. Basically, every form would have its own presenter and would only get and set properties of any of the controls on a particular form using its view. Populating controls-a call to a db to populate a combobox for example-is located in a public service class. Any validation of user inputted data is located in a BO class which can be reused by any and/or all of the presenters. I hope this helps.
In my CAD-CAM system my presenters don't use user controls. User controls reside in the view which reside in a EXE assembly that implement the view interfaces the presenter use.
If want to display a list of customers I hand it off to the view which has a DisplayCustomerList and it uses whatever combination of user controls it needs to display the customer list. If multiple views show the customer list in the same way then in the ExE/View assembly they share a user control or class for doing that. That class doesn't go outside of that assembly.
Our software is adapted to run many different types of metal cutting machine. So we place a lot of emphasis on being able to rip off the UI and replace it with a completely different UI (corresponding to a different machine). All of these UIs reference the same set of core assemblies.
The hierarchy looks like this
View EXE
Presenter Implementation
Command Assembly - commands are executed by the presenter that modify the model
Presenter Interfaces
Model Assemblies
Off to the side are loadable assemblies that define dynamic content like what file types can be loaded, reports, cutting device drivers, etc. These implement various interfaces found in the model assemblies
One thing I do is that I don't impelment a view presenter for every dialog. If the dialog is tightly bound with a command then it is defined, created, and used along side the command class. Occasionally a group of related commands will share a dialog (File handling for example).
The essential question I ask when using MVP is "What happens if want to completely replace the forms with something else?". The answers to that question will identify where you are too dependent on a particular user control or form engine.
The biggest problem (and one that I haven't got a good answer for) of my setup is that current IDEs and langauges make it very easy to tie user controls to database records. It is so productive compared any other setup it tends to dominate the design. I haven't had to deal with the issue much in my CAD-CAM application so I don't have any answer other than passing the dataset to the view and let it handle it. This site has some patterns that may be of use in this situation.
The more I learn about WPF and XAML, the more I realize that you can do pretty much all of your GUI initialization and event handling glue in either XAML or in code (say C# code or VB.Net code).
My question is to those who have been working on WPF for longer and ideally those who have shipped apps with it -- where did you find was the best place to 'draw the line' between XAML and code? Did you use XAML wherever you could? Only where interfacing with non-coding UI designers?
Any tips in this area would be extremely helpful to myself and other coders who are just getting into WPF programming and are kind of paralyzed by all the choices we can make!
One thing that I would look at is the model-view-view model pattern. It is a very elegant pattern which naturally separates everything into nice buckets ... including your xaml.
For example, it helps you keep a clear boundary between the developer and the designer and even allows for test driven development.
There is a whole bunch of info out there on it, but I would start with John Gossman's blog posts:
http://blogs.msdn.com/johngossman/archive/2005/10/08/478683.aspx
http://blogs.msdn.com/johngossman/archive/2005/10/09/478894.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/26/539598.aspx
http://blogs.msdn.com/johngossman/archive/2006/02/27/540304.aspx
http://blogs.msdn.com/johngossman/archive/2006/03/04/543695.aspx
http://blogs.msdn.com/johngossman/archive/2006/04/13/576163.aspx
Update:
Just want to point people to another StackOverflow post with lots of good info on M-V-VM in it.
One tip is to not declare event handlers in XAML. Instead, name your elements and attach events handlers in the code-behind. That helps keep a clean separation between the designer and developer.
As others have suggested, try following the Model-View-ViewModel pattern. However, it's OK to put stuff in the codebehind! The rule is that if it's "View" related, you put it in the Xaml or the codebehind (whichever is more convenient for you). If it's more business logic related to how the user interacts with the system, then it belongs in the ViewModel. If it's just business logic not concerned with interaction, it belongs in the Model.
Examples of each would be:
Model: defines a property called ModifiedDate that stores the last time it was modified.
ViewModel: converts the ModifiedDate into an enumeration property called ModifiedAge, based on when it was modified: Yesterday, In the Last Week, In the Last Month, In the Last Year, etc.
View: converts the ModifiedAge property to a background color where more recently accessed data is highlighted bright yellow, and less recently accessed data is more of a beige-khaki-gray that your designer insists is called "Meadow Lark Lilly Flowerpot".
Another tip is to separate XAML into functional and aesthetic. Developers would typically work in the functional XAML whilst designers care primarily about the aesthetic. This keeps the functional XAML very easy to grok, which is important because developers often need to edit such XAML. Aesthetic XAML is typically edited by designers using tools, so its neatness and verbosity is less of an issue.
I did a bit of a blog post on this a while ago here.
Don't lose sight of the fact that XAML is code. It's declarative and all that, but it's still a programming language. In fact, it goes through a conversion to C# or Visual Basic before it's turned into IL for the .NET compiler to chew on.
I'll echo Scott Whitlock's comment: MVVM is a great way to separate concerns and focus on architectural details. It's really, really OK to put stuff in your code-behind, especially the stuff he describes. If you don't have a requirement to separate designer from developer, then adapt the MVVM pattern to your specific needs; don't try to force yourself to be pure or idealistic about it.
It's also perfectly OK to put calls to your ViewModel's methods right in the View code behind, if you don't need the flexibility of commanding with ICommand classes. Or if you know the View you're making will always be bound to the ViewModel class you're making. Or you could take things a step further, define an interface for your ViewModel, and bind only to implementations of that interface. Then you can still swap out the ViewModel whenever you want.
Stuff like that.
When you follow a proper pattern like Mode-View-ViewModel you will get opportunity to do more on XAML side and less on code behind. Maximize the usage of RoutedEvents and Commands in WPF code.
When building UserControls I try to Xamlize as much as possible.
One tip I found in the field is that creating ControlTemplate and DataTemplates by hand is really a pain in the ***... I always write those in XAML....
I would say use as much xaml possible, using Binding, commands, styles, templates etc. I had to support functionality of saving and loading templates using XAMLReader/XAMLWriter and it more easier for controls having more xaml.