I'm trying to use CollectionViewSource to display some data, and all the examples/tutorials I've seen have a custom class built, which they use in another class, which inherits from ObservableCollection. I'm new to both using CollectionViewSource and this is only my third implementation of MVVM, so I might misunderstand the programming pattern, but my question is:
where do I put the ObservableCollection class and/or custom class?
I feel like they should go in the Model, but then I'm not sure what gets bound to the View. Do I just build these as external classes, and then reference them in Model/ViewModel?
Any help is appreciated
Firstly, I would say that there is no need to inherit from ObservableCollection<T> unless you are adding functionality to it which I have rarely, if ever, actually needed to do.
In most cases I create ViewModel properties of type ObservableCollection<T> and then populate them from the Model whenever I load the data. This has the advantage that the Model does not need to use ObservableCollection<T> (it can be any IEnumerable<T>) and it means that later when I (almost inevitably) want to wrap whatever I'm getting back from the Model in another instance-specific view model I am only obliged to change my existing view model classes.
Once you have a property on your view model you can simply bind your CollectionViewSource to that property and it will do everything from there. It's worth noting that the CollectionViewSource doesn't actually care about the type of the property, so you can expose your collection to the View as an ICollection<T>, IEnumerable<T> or (I believe) even as an object and the CollectionViewSource will still treat it the same as if it is exposed as an ObservableCollection<T>.
Sorry for the slightly rambling answer. The concise version would be "it depends on the situation" but I tend to follow this general approach in most cases.
Related
In my WPF application, my Model class inherits from a class ParentClass as such:
Model : ParentClass, INotifyPropertyChanged
My application is simply meant to provide a UI to test and validate ParentClass. So Model really is not much more than an INotifyPropertyChanged implementation layed over ParentClass
However I still need to access the data from that parent class and have it be responsive to the UI.
Assuming Slicing is a property in ParentClass, and WPFSlicing is a property in Model, this is how I am currently doing it. I am wrapping every parent property in a WPF-compatible property.
public Thickness WPFSlicing
{
get { return Slicing; }
set
{
Slicing = value;
OnPropertyChanged("Slicing");
}
}
Is there a smarter way to do this? I have many properties in my parent class and this seems like a very uninspired method.
This is a very interesting question.
Typically, I've found that in MVVM applications, you're trying to isolate a model as an end-result -- a product/piece of data -- of the View Model. If you were to have a Bicycle shop, for example, you would see the Storefront as the View, the Sales Person as the ViewModel (assuming this is a customizable Bicycle that is built to order), and the Model as the finished Bicycle object.
In the case of building the Bicycle, while it is in a "prototyping" stage that needs to be represented, I tend to wrap that up in a ViewModel -- because there is logic in it. It seems like an extra step, but in the end, you can have validations at that ViewModel while constructing it. If your model is inflexible to have the INotifyPropertyChanged added to it (or if it was generated from a service), you'll have issues if you have "0" tires on the Bicycle -- that should cause problems!
A lot of folks tend to get a little lazier and see MVVM as a pattern that abstracts out prototyped models (where data input is going back/forth, updated) to models -- when they should in fact be ViewModels.
Per the example, I would have an MVVM Directory that looks like:
Models
-Bicycle (an object that can be passed across a service, etc -- data)
Views
-BicycleCreatorView (the view or data template of the model)
-StoreFrontView (the view of the entire store/app)
ViewModels
-BicycleCreatorViewModel (the view model which CONSTRUCTS a Bicycle model as the end result)
-StoreFrontViewModel (the view model for the entire store)
Now, you could very easily ALSO have the BicycleCreatorViewModel have a constructor which takes in a Bicycle model and pre-populates. That's not uncommon. Someone might come into a store and say, "Hey, can you make this similar to this other one? Here's what it looks like." While the end-result is to have another property (probably just a get {}) which actually renders a Bicycle object, IF validation is good and we don't have something unusual with 0 tires, no seat (maybe that's a feature?), etc.
So, in short -- I would always have your Model (if you cannot extend it in ANY way) be wrapped up into its OWN ViewModel, for this purpose. That would be the true MVVM pattern. You can always use stuff like ReactiveUI or other toolkits that can wrap the properties up. You may spend a little more time doing this, but the end-product will be far more flexible and less error-prone than one otherwise. Essentially you are doing this already, but you could probably rewrite it so it seems "cleaner" and has the line's drawn.
In theory, you might also inspect whether you could approach it in a method like this:
Is there an aspect-oriented toolkit you could use, potentially? Maybe make your classes partial to include INotifyPropertyChanged on the extension and then XmlIgnore certain pieces, if serialization is an issue/at question?
Problem is we have very little knowledge on where the model comes from and how you're using it. Hope that helps or gives you an interesting idea. Would love to see if you come up with a solution that is more "inspired" than the standard.
I offer an alternate view. This all can be extremly simply solved with AOP framework, such as PostSharp. All you do, is attach [NotifyPropertyChanged] attribute to your class, and your model has everything wired up.
http://www.postsharp.net/aspects/examples/inotifypropertychanged
Be warned though, it costs, but it can be good investment, imo.
Ps, it's matter of view, but I don't see anything wrong with having all the DOMAIN model classes implement INotifyPropertyChanged. It doesn't kill performance, the only downside is that it clutters the code a little. That's what I have done, my domain model entities implement from CommonEntity, and INotifyPropertyChanged. INotifyPropertyChanged is not part of WPF!
It works, and is definitely nicer than wrapping your models inside viewmodels.
I'm designing an MVVM framework and I need to know if my understanding of MVVM pattern is correct or not. My question is simple. How should I pass the ObservableCollection object between the VieModels? or shouldn't I?
I have a CustomerViewModel which has an ObservableCollection to hold a list of customers. I also have an InsertCustomerViewModel which is responsible for insertng new customer models in to that ObservableCollection. in the InsertCustomerViewModel I have a method called Insert() which is called everytime the user clicks on the Insert button.
What I'm doing so far is passing the ObsertvableCollection from CustomerViewModel to the constructor of the InsertCustmerViewModel and then in the Insert method I have Items.Add(newCustomer).
Is my implementation correct? or is there any better way to do the job?
I would pass the CustomerViewModel to the InsertCustomerViewModel and expose a property for the collection. That way you can use and modify that collection from InsertCustomerViewModel directly.
From my point of view InsertCustomerViewModel does not make any sense here. When user insert a customer it should only add in CustomerCollection Class which should be a Model for multiple ViewModels.
I think the idea should be share the same CustomerCollection model among the two ViewModels via some common instance.
I've created a sample app, just to test and try out some of wpf's capabilities. I was basically trying out the databinding in wpf, and did the rest of stuff more or less quickly. THen, i faced an arquitectural problem (yes, should have thought in advance before starting coding :) ) and i wanted to know what's the best refactoring solution for it.
I have a simple interface that returns a list of objects, based on a defined process.
public interface IDoStuff<out T>
{
IEnumerable<T> Do(string someParam);
}
i've created a couple of implementations for this interface. Then i have a view in wpf, which has a dropdown with hardcoded values, and depending on what you select, instatiates the implementation of the interface and populates some list
foreach (var item in new IDoSTuffImplementation1()<MyObj>.Do("imp 1"))
{
MyObjs.Add(item);
}
ater on MyObjs is the DataContext for a listview, and displays things and so on and so forth, but it's out of the main question.
this is all hardcoded and not very nice. If i was ever to implement a new interface, i'd need to add it to the dropdown, and create a new foreach for that specific implementation (more duplicated code)
Ok, here's my impression on making this better/refactoring for extensibility.
I was thinking a good approach would be to use some kind of MVVM pattern, making the wpf view into a view + viewmodel. the viewmodel would use some kind of IoC like spring, which would (by xml) instantiate one specific implementation of the interface, and inject it to the viewmodel, which would then call its "Do" method and everyone happy. So this way, the only thing that would be needed to do when we implement a new component, is to add it to the xml config file.
Suggestions, Comments? what's the best approach, if any?
thanks!!
Actually I don't see any architecture changes if you provide another implementation of the interface. You already have a good architecture when using MVVM, so the task you are trying to accomplish will not change the architecture, but will extend your application using the architecture.
I suggest you change you Method to a Property instead. And assign that property to ComboBox's ItemsSource property to ease up your coding using data binding.
I googled for an answer to this for more than two weeks now. This usually means either I am blind or the idea is absurd. Anyways:
In a middle-sized, quite flexible project I'm storing configuration data in a hierarchical structure in the like of this one:
Configuration (collection)
Audio (class)
BaseDir (struct)
PlayMode (enum)
Input (class)
CalibrateOnConnect (bool)
KnownDevices (collection)
... (class)
...
UseDevice (integer)
Playlist (collection)
FirstAudio (class)
Path (string)
Repeat (integer)
...
I already managed to display these in a TreeView in a MVVM pattern. Since I can't exactly tell which options will be added in future, I used a generic approach, creating ViewModels for class, ienumerable, my custom structs and the basic value types (string, bool, enum, ...).
In my XAML these have their corresponding (Hierarchical)DataTemplates, e.g. with a CheckBox for booleans or a textblock for general value types.
Each ViewModel instance has a field to store the data of the underlying Model.
I manage to edit these values in the View and via TwoWay-Binding also in the ViewModel.
But what makes my head hurt is how to update this data in the Model.
Since I create the hierarchical ViewModel structure through reflection, the parents do not have get/set properties corresponding to the field names / indexers / ... of the equivalent configuration class / collection. Though each ViewModel instance knows the field/property name of the parent's model's data structure it was created from and knows its parent ViewModel instance, too (but not its parent Model instance).
Every attempt to solve this problem via Commands or by calling some parent's update function made a knot into my brain.
Isn't there a simple way to achieve this via regular binding techniques?
Would it be better if I created ViewModels for each configuration (sub)class I'm using?
Hint: Each ViewModel instance knows its field / property name in the parent's model's data structure.
Reading through the comments I'd argue that a view model should be tightly coupled to the model that it is trying to represent. Having a dynamic view model is also very hard to test.
However, if you really wanted to try to get around this, you could consider using a DynamicObject which allows you to get/set properties on the instance in a completely generic fashion. With DynamicObjects you are then given hooks that are called when a property is either set or got, this would enable you (for example) to raise NotifyPropertyChange events for a given dynamic property.
Can anybody explain me what a dependency property is in WPF and what is its use. I know there are a lot of tutorials on google for it, but they teach how to create a dependency property. I am confused as to where I would use it. I mean will I use it in XAML? If anybody could explain me in simple terms, that would be great.
It would be nice if a simple example is shown along with XAML, with example, of how I might use the property, and what would be the effect after I use it.
Thanks a lot for all your answers..
The many links listed should give you a good idea of what dependency properties are, but in general, the easiest way to think about them I believe is the following:
Dependency properties are what you need to use for properties of user interface elements, if you want to be able to bind them using WPF's data binding. In order to be the "Target" of a data binding operation, you'll need to make the property a Dependency Property.
When you're implementing a standard class (which becomes the DataContext of a "control"), you'll want to use INotifyPropertyChanged instead of DPs. This allows that class to be a binding "Source".
In general, you'll only want to make Dependency Properties if you're making something that will be bound in XAML, as the Target of a UIelement. For example, say we have XAML like this:
<local:MyControl ControlProperty="{Binding SomeProperty}" />
Normally, ControlProperty will be a Dep. Property, since it's the binding target, and SomeProperty will be a standard CLR property (not a DP), in a class that implements INotifyPropertyChanged.
A Dependency Property does not store its value in a field, but rather in some hashtable. Thus it needs less memory, which is important especially for GUI objects, because most properties will retain their default values und thus those don't take up any more memory. Dependency properties are a bit slower though, because of boxing to and fro object and looking up in the hashtable.
The Dependency Object framework furthermore allows for a lot of features like change notifications etc. I found a good resource that explains the inner workings here: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c33a8359-58be-430d-b949-cb6e6f32d8aa
I agree the syntax to declare them is a bit ugly, but you can create helpers to alleviate that a bit.
This is probably the most straightforward article describing DPs:
http://joshsmithonwpf.wordpress.com/2007/06/22/overview-of-dependency-properties-in-wpf/
Personally, I use them most often when I need to expose properties so that they can be databound via XAML. For example, if I make a UserControl that I want to use in XAML, and I want to set a property on the UserControl via XAML, I expose it as a dependency property.
What you're looking for is chapter 3 of WPF Unleashed. It's a free sample chapter.
the best use I saw for it is for attaching properties to classes which you cannot modify. So if you get a third party assembly you can attach extra information to the classes and read them when you need to.