Treeview inheritance relationship - wpf

Hallo,
I am trying to visualize a hierarchial (Is-a) class relationship using Treeview with WPF but I find it difficult.
I studied some code from the Internet like
http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx
These examples show a (has-a) class relationship and in this case the visualization with WPF+Treeview+Databinding is quite clean and intuitive.
On the contrary What I have is
public class Device() { }
public class VisionDevice() : Device { }
public class CommunicationDevice() : Device { }
public class SerialComm() : CommunicationDevice {}
public class Webcam : VisionDevice { }
I would like to visualize a WPF treeview structure like that
Device
VisionDevice
WebCam
CommunicationDevice
SerialComm
It is possible to do that using HierarchicalDataTemplate but the solution I found is not very elegant.
In conclusion: Treeviews is good for has-a class relationship but difficult to adapt to is-a relationship. Do you agree?

In conclusion: Treeviews is good for
has-a class relationship but difficult
to adapt to is-a relationship. Do you
agree?
Yes, tree views are good for structures where you know the root and have a connection from that to all its children (e.g. an object knows its properties and those properties are in turn objects which behave the same way), for types it is quite problematic since the traveral is the other way around, the supertype knows nothing of its subtypes but the subtypes know their supertypes (unlike objects which rarely have a reference to their parent).
To visualize types you would first need to collect all the leaves and while going towards the root check which types have a branch in common till you arrive at your target supertype. Not very elegant...
(Alternatively you can start at the root and query all types every time to see if their immediate parent is the type you are currently looking at, in terms of performance that should be even worse)

Related

Brand new WPF Application, MVVM, and how to use POCO partical classes generated from ADO Entity Data Model....?

I've asked this before, but I actually still needed help...
Here's the scenario:
I'm starting a new WPF application, and want to use MVVM. Because our DBA has created a database with tables we need to perform CRUD operations on, I used the Database First approach (ADO.NET Entity Data Model functionality) and got my .edmx, .tt, dbcontext partial classes, etc. created for me.
Now, where do I go from here with the MVVM approach? I do not want to use a framework, and want to get the basics down of MVVM first, before I use external tools. Is there a tutorial anywhere that can help me just get started?
Again, sorry for asking this again, but I really can't find any help, and I have to use the stuff our DBA created.
Your question is really broad, but you might want to start out by deciding how your ViewModels are going to get their data and submit their updates through the EF classes.
While you can bind your EF types directly to your view I've found that a better approach is to keep your ViewModels separate from the ORM model types as much as possible. Model the needs of the View in terms of the behaviours (ICommands) and data (ViewModel props or child ViewModel props or ObservableObjects) apart from the EF types.
Then create a service type that can be injected or instantiated within the ViewModel that will interact with the data model directly and translate the ViewModels into Data Models and vice versa. You can either do that work manually, with LINQ/Lambdas, or using something like AutoMapper to define the relationship between your ViewModels and the data Models (EF Types). This maintains a clear line between the data schema and the ViewModels and I think you'll find changes in the data model having less of a ripple effect on your app this way.
That middle layer that I referred to as a 'service type' might just be some type that exposes a higher level interface than a repository focused more on business operations than on crud operations, but internally makes all the repository or EF calls on behalf of the viewmodels.
If you want to avoid using a framework that's fine, but you still should probably download the MVVM Light core libraries and have a look at what's included. Its pretty lean and will give you the basic nuts and bolts to support MVVM. You can choose to roll your own after that if you wish, but it might not be worth it.
EDIT: Since you said you're short on time...while I don't encourage it, a more expedient but less robust solution might be to just bind your views directly to your EF types as properties of your ViewModels.
// Using the ViewModelBase included in MVVM Light
// which gives you the special Set() method
public class EditCustomerViewModel: ViewModelBase{
public EditCustomerViewModel(){
_currentCustomerCommand = new RelayCommand(SaveCustomer);
}
private Customer _currentCustomer;
private void SaveCustomer(){
using(var ctx = new EfDataContext()){
// Save operation here
}
}
public Customer CurrentCustomer{
get { return _currentCustomer; }
set { Set(()=>CurrentCustomer, ref _currentCustomer, value); }
}
public ICommand SaveCustomerCommand{ get { return _saveCustomerCommand;}}
}
Then in your view you can bind your controls, whatever they may be to the CurrentCustomer properties. You can do your EF save via a command, displayed here as an implementation of the MVVM Light RelayCommand. So, quick and dirty approach could work, but if you can try to abstract the data models away from the ViewModels by presenting the data in types crafted explicitly to to serve the needs of the view.

One Model Entity, Multiple Pages -> Multiple Views? Multiple ViewModels?

Due to limited screen real estate I will be capturing user input for a single entity using multiple pages (displayed consecutively - think wizard). In my model I expect it is correct to model this entity as a single class.
In an MVVM implementation I am assuming it is best MVVM practice to consider each page as a seperate View. Is this correct?
Is there a consensus on the best MVVM practice for whether each Page has it's own ViewModel or should there be one ViewModel instance that is referenced by the multiple Pages?
To illustrate:
Option 1
Class A (X, Y, Z)
ViewModelA1 (X)
ViewModelA2 (Y)
ViewModelA3 (Z)
View1 captures ViewModelA1
View2 captures ViewModelA2
View3 captures ViewModelA3
Option 2
Class A (X, Y, Z)
ViewModelA (X, Y, Z)
View1 captures ViewModelA.X
View2 captures ViewModelA.Y
View3 captures ViewModelA.Z
The word "View" says it all. It's a view of the data. The ViewModel's job is to make the data coming from the model presentable. Whatever needs to be done to the data happens in the viewmodel so that the view can show it.
Normally you will have a one to one relationship of you view to viewmodels, because normally you only want to show that data in one way. (one "view")
Where I deviate from the normal practice (possibly from MVP pattern?) is that if you want to show the data in a number of different ways (for example you want a bar graph or a line graph, or a pie chart) and the data is the same for all of the views then you only need one viewmodel. Its a case of the DRY principle. If you have three viewmodels and they are all the same, then use one viewmodel. Multiple Views. One viewmodel.
I'm sure there are folks that would argue strongly one way or the other. From my perspective, it all depends on what code you need to re-use. There are both View-centric and Model-centric ways of constructing your ViewModels, and I don't think that either one is always going to be the right approach.
If you find that your ViewModels tend to be heavy on UI-specific logic, a good design will tend towards a 1:1 relationship between Views and ViewModels, with each ViewModel wrapping multiple Models. The danger in this approach is that you can spend a lot of code wiring up the data in each ViewModel and keeping it in sync, and this wiring would need to be repeated across each ViewModel. Uggh.
However, you may also have a situation (as I do in my current project) where the ViewModels have to cope with complex relationships in the underlying model, and where the various Model entities can be updated from multiple endpoints (i.e., either the user or a duplex WCF service). When this is the case, you spend a lot of time in each ViewModel making sure that its data is in sync with the underlying models, and it would be silly to re-do all that logic in each ViewModel. In this scenario, I've found that the cleanest approach is for your ViewModels to map more-or-less 1:1 with models, and to be re-used across multiple views. The downside to this approach is that you can end up with a lot of UI-specific code from various different Views mixed into the same class, and that can make it hard to test and maintain. (Yes, I know that ViewModels are supposed to not be tightly coupled with any specific UI, but you still end up with a lot of code that says, in effect, "When the user executes this command bound to some UI element that I'm pretending not to know anything about, do this other thing that I'm pretending I don't know is going to result in a dialog box being raised." Even at that level of abstraction, the logic coded into the ViewModel can vary from View to View.)
Then there are various hybrid approaches, which are likely the most helpful in real-world scenarios. For instance, you might end up employing an inheritance hierarchy within your viewmodels, so that you deal with the generic wiring in one or more base classes, and then add in the UI-specific pieces in the classes further down the inheritance chain.
For what it's worth, one of my frustrations with most MVVM articles and what-not is that they deal with excessively simplistic scenarios that don't reflect the complexity you find in the real world. As soon as you get past a Customer -> Order -> OrderDetail sort of form, I've found that most of the recommendations I've read tend to breakdown, and I'm left finding my way on my own.
Relevant best practices, regarding MVVM, as I was taught (and practice):
Each page/View has a single ViewModel.
The ViewModel should only have fields/properties relevant to the View that uses them.
ViewModels can be combined from multiple underlying logical Models/classes as appropriate.
The above can end up with more models but they are easier to work with over time as the changes to a single View/ViewModel don't impact other Views or ViewModels
This matches your first option.
In an MVVM implementation I am
assuming it is best MVVM practice to
consider each page as a seperate View.
Is this correct?
Yes, I would do so depending how complex is it. I think that MVVM for most of the WP7 apps is just an overkill.
Option 1 is the better model to use.
I am not sure what you mean with the X, Y and Z.
You should simply pass the same instance of the model to each ViewModel
Class Model
{
string X { get;set;}
string Y { get;set;}
int Z { get;set;}
}
Class MainViewModel
{
// constructor
ViewModel()
{
model = new Model()
SubViewModel = new SubViewModel(model);
}
Model model {get;set;}
SubViewModel sub { get;set;}
}
Class SubViewModel
{
// ctor
SubViewModel(Model model)
{
this.model = model;
}
Model model { get;set;}
}
The MainViewModel handles navigation between each SubViewModel, but they are all looking at the same instance of the Model, so they all have the same data.
On some Tasks I may have multiple models associated with a single ViewModel and multiple views for that Task. For Example, Creating a product with grouping, images, etc.. Focused around the product.
I also have Tasks where multiple ViewModels are used driven by the Task through multiple Views. For Example, Creating a User account in the application with a mashup of multiple 3rd party accounts like Facebook, Twitter, etc where each 3rd party API has it's own set of requirements but appears as a single Task to the user through a series of steps. Focused around the User account.
MVVM pattern is flexible dependant on the need. Define the task, break it down, and decide on which best suits the task.
Look, what are you asking is this:
I have 1 M.
I have 3 Vs. (Assuming that it's preferable for you to create 3 Vs).
Should I have 1 VM or 3 VMs ?? In other words you ask, in which side the VM concept is closer ? On the M or the V side ?
From my experience thus far with the pattern, the VM is MUCH more closely related to the V.
So the quick answer to your question is: 3 VMs (Option1). Option 2 is the wrong way to think of this pattern.

ViewModel tree vs. frequently updating Model tree

In my WPF MVVM application my model is a complex tree of Model objects wich constantly changes at runtime. Model instances come and go at runtime, change their position within the tree and of course change their many properties. My View is almost a one-to-one visual representation of that tree. Every Model instance is in 80% of the cases also a node in the tree.
My question is now how I would design the ViewModel around this? My problem is that there are quite a lot of different Model types with each quite a lot of properties. If I understood MVVM corretcly the view should not communicate with the Model directly so this would mean that I would have to create a ViewModel type for each Model type and have to rewrap each property of the Model type in the ViewModel.
Also the ViewModel would need to "bind" to the propertychanges of the Model to pass it along to the view (using wpf datatbinding). I would need some factory that creates and introduces a ViewModel instance for each Model that appears anew and I would habe to dispose each ViewModel instance when the corresponding Model disappears. I end up keeping track of all instances I created. It is unbelievable how much bloat code is generated dues to this double wrapping.
Is this really a good approach? Each entity and each property more ore less exists twice and I have a lot of extra code keeping Model and View in sync. How do you handle this? Is there a more clever way to solve this?
Does anyone have a reference/sample implementation for this that does it better than I do?
I think you may run into trap of paradigm if you follow this path. MVVM is nothing more than a pattern, which simplifies development in WPF world. If it doesn't - don't use it or revise your approach. I wouldn't spend 80% of my time just to check the "Using MVVM" field.
Now back to your question. Correct me if I'm wrong, but it sounds like you are looking at MVVM from opposite direction: you don't need Model to ViewModel one-to-one correspondence. Usually you create ViewModels based on your View first, and only then on a Model.
Generally you look on a screen mockup from graphic designers, and create corresponding ViewModel, which takes all necessary fields from the Model, wraps/modify/format/combine them to make View development as easy as possible.
You said that your View is almost one-to-one visual representation of the Model. In this case it may have sense to create a very simple ViewModel which exposes root object of your model-tree, and let View consume model directly via that property. Then if you need some View customizations or commands processing you can delegate that to ViewModel.
Sorry for very vague answer. Maybe if you ask more specific question we could dispel the confusion :)...

MVVM Experts need your opinion on MVVM and Dataforms

as far as I understand the ViewModel should abstract the model from the view and add additional logic to handle the presentation stuff.
My question is:
How would I create a dataform that is suppose to handle user input for an order and details at once.
It should present fields for entering the orders as well as the fields for 1 detail.
My Model would have an object for an order which contains a list of OrderDetails.
How would look my ViewModel for my OrderEntryForm like?
Would I have an OrderViewModel and an OrderDetailViewModel and my
my OrderEntryForm would contain a property of OrderViewModel and one for OrderDetailViewModel? (nesting ViewModels?)
How would validation be handled in this case? Since Validation should go close to the model?
Especially when I work with RIA-Service...
Wouldn't it make more sense to put it in the ViewModel?
How far would you abstract the Model from the ViewModel?
Example:
private DateTime _OrderDate;
public DateTime OrderDate
{
get { return _OrderDate; }
set
{
if (_OrderDate != value)
{
_OrderDate = value;
OnPropertyChanged("OrderDate");
}
}
}
this would mean I have to map the ViewModel-Property to Model-Properties. Cannot leverage Validation-Logic from the Model here...
This example:
public DateTime OrderDate
{
get { return Model.OrderDate; }
set
{
if (Model.OrderDate != value)
{
Model.OrderDate = value;
OnPropertyChanged("OrderDate");
}
}
}
would requiere to pass in a Model. Have the access to the validation logic of the model but also a coupling...
Most examples on the web show dataforms which use ViewModel's that a just a representation of the tables not a real abstraction...
I know and I saw this
stackoverflow.com/questions/744474/combining-net-ria-services-and-mvvm-in-silverlight-3-0
I also read nikhils blogpost on this but this handles also only Products straight mapping from the tables of the database... =(
I know alot of questions...
What are your opinions on that topic?
How would you handle complex dataforms?
Chris,
I have had the same issue and end up implementing it in a crappy way :-( (two vieModels one per view, but passing the parent to the child View... bad stuff).
From my error I learn that next time I would give a try to:
Generate a single ViewModel, but in the child view pass a detail entity in the datacontext (this detail entity does not have to match with the proxy generated entities, maybe is a container of that entities).
Generate a singleton controller class: this class won't be exposed to the view, it will be transparent for the view, just the detail view model will ask the controller for that dependant data instead of going to the DAL.
Not sure if this are going to be clean solutions, have to give a try and fail :).
I agree with you... there are not real samples with this kind of scenarios.
What do you think?
Thanks
Braulio
PS: About validation, if we create our own super entities, we can there define our validation, in my case I have tried as well extending the entities using partial cases and then I can have an entity myPhoneNumberDetail with my special validation.
I personally think there are no hard and fast rules... well, there is one - be pragmatic.
Pragmatically speaking, a view model is a model, and so is a data model. Both are classes, independent of the UI, and surface state as properties, operations as methods, and notifications as events. The thing that I think in my mind differentiates them is how general they are. I see a model as generally usable across multiple views, vs. a view model optimized for a particular view.
I would personally never abstract for the sake of abstracting. I would never surface top-level properties for every model property and implement it by delegating to an underlying model. This increases work. It increases the amount of code to be tested. It requires propagation of metadata, change notifications etc. If there is some actual logic to add, then yes, there would be properties on the view model I'd expose and delegate to the underlying model as appropriate. Even there I'd ask if it is reasonable/appropriate to expose those as computed properties on the model (view model and data model are both models).
As far as surfacing DAL types directly vs. not, that in my mind is somewhat orthogonal. It depends on other factors - how much do you want to abstract the DAL, how useful a DAL type is - for example, if a DAL type has a lot of foreign keys, a presentation model equivalent or projection might be more useful where there is some denormalization done. Sometimes security might be the reason to write a presentation model/projection - eg. I don't want to send email addresses to the client, and instead want an alternate representation of email addresses.
In my sample, I used a DAL type directly, to simplify and not have an overload of concepts in a single sample. I do want to blog about presentation models and projections in a dedicated manner... and so didn't want to mix posts of viewmodel and .net ria services with presentation model concepts at the same time.
As is so often, with patterns, it really depends. The ViewModel can expose the underlying model, and there is no hard and fast rule that says you "must" hide everything and delegate. I have spoken to many folks that are strict adherents to LOD and still they agree that in the case of UI binding, it does not apply.
Now in the case of whether that model is a DTO or not there you will find a lot of differing opinions. Some believe that the only thing that should ever be on the client is a pure projection i.e. a DTO with all logic living on the server, while others believe that that moving entities between the tiers is fine. That would be an discussion for a different post. :-)
In general the guideline that i would recommend is always at least have a high-level VM which can be used for screen state, etc.
As far as child models, like OrderDetail, then if the child model is sufficent to just bind to then just expose it directly. Now one thing to consider is around notification, if you model is not implementing INPC than you may have no choice but to wrap it in order for binding to properly work.
Even if it implements INPC there may be view-specific concerns that that model does not contain, but which are required to for the view to function. In that case I would use simple aggregation and create an OrderDetailVM that directly exposes the underlying OrderDetail and adds additional properties.
For example
public class OrderDetailViewModel
{
public OrderDetail OrderDetail {get;set;}
public bool IsValid {get;set;}
}
Where IsValid is checking some screen-specific logic.
It really depends though on how much encapsulation you want to achieve. I wouldn't find anything wrong with using a delegation model. Depending on the complexity though it might get unwieldy, for example imagine if OrderDetail had additional children, etc.
HTH
Glenn
To clarify, the VM is an abstraction of the Model, not of the View and not the other way around.
You can certainly use multiple VMs to correspond to discrete portions of your View. If you're not going to need separate VMs for Order and Details, you can just have an OrderAndDetialsViewModel that contains everything, and the whole View will bind straight to that. This is where the abstraction comes in.
You are right, that your model's validation logic is going to be distinct from your ViewModel's validation logic, if you put any in there. In no case will the validation be in the View.
I'm not sure I follow your second example. What is the Model object? Your VM may know about the Model(s) from which it is composed, but it is not going to expose it/them as such directly to the View.
I hope this helps somewhat. Please let me know if there is any part of your post that I failed to address.

why not partial class to build the ViewModel in MVVM pattern?

Why not use partial class to build the ViewModel?
Since the definition of viewmodel classes have some definition of the data classes of datamodel, why not try to reduce some work, extending or making partial classes of the datamodel, completing them with command and etc.
In some cases this may be useful, but generally the ViewModel (or PresentationModel) has a different set of concerns that would muddle the rest of the model.
For example, imagine that you have an object model that represents an order processing workflow (everybody's favorite example.) This same model might be underlying a WPF, a web site, and perhaps even other services.
Within the WPF application there will be WPF-specific concerns for presentation. Adding these concerns to primary model (even as partial classes) results in a violation of SRP. Ultimately, it would obscure the intent of model and make it difficult for consumers of the model to know which parts of it where essential and which were incidental.
I agree but there are also extensions that seem to belong in a partial class as well. For example, a calculated field (say an invoice total), useful on the client and perhaps the viewmodel exposes it for data binding to the UI, however it's really a property of the entity. It may not be represented in the model itself because it can be derrived from the entity's other properties, and IMO better represented by using a partial class to extend the domain entity.

Resources