I have a View that is hooked to a ViewModel. I have a singleton class that's exposed by foo.Current. I have a property on that class that will be changing as the result of a button click command calling a foo.Current function. I want to be able to bind a textbox's text to that value and when that value updates the textbox will update. My ViewModel does implement INotifyPropertyChanged and I have other properties on the view model that update controls fine. What is the best way I can make that singleton class update my ViewModel with the new value?
I'm thinking I need to figure out a way to make the Singleton class update the ViewModel.
There's no "best" way in current situation, options are as follows:
Define a property in your viewmodel and pass that viewmodel to your singleton. Singleton should change the relevant property along with it's own.
Move properties from singleton to viewmodel or include singleton in the viewmodel itself
Create an event for changing the property on the singleton
Inherit singleton from INotifyPropertyChanged and in your VM attach to PropertyChanged event of singleton. And monitor your property name.
...
Easiest one would be the first option though there might be some architectural inconsistencies in your app that should be treated.
If I understand you well, I would use Observer pattern.
Related
Say I have a property named Location of type Point in my ViewModel, to which my View binds. I'm using MVVM Light's ObservableObject and RaisePropertyChanged setup to raise property change notifications. The problem is that when I execute the following in the ViewModel:
this.Location = new Point(100,100);
my View updates correctly. But if I do:
this.Location.Offset(10,10);
my View doesn't update, means the Location property does not notify the View about the change. Why is this so? How do sub-properties of built-in types such as Point or Size deal with change notification?
The fundamental problem is that Point is mutable.
You could write your own ImmutablePoint that allows conversion to and from the existing Point class for API compatibility, but doesn't allow methods like Offset.
It's not an ideal solution, but it gets around the problem of changing the fields on a property rather than the property itself.
In MVVM land, your ViewModel is responsible for notifying the View when properties change. The majority of the .NET classes do not implement INotifyPropertyChanged themselves, so you won't get automatic wiring when using them. You'll have to raise PropertyChanged yourself on the Location property each time you modify any properties of Location
Alternatively, you could implement your own Point object that implements INotifyPropertyChanged.
You can add INotifyPropertyChanged to your class members automatically using either Castle Dynamic Proxy (which wraps your models in a proxy at runtime) or PropertyChanged.Fody (which modifies the model's IL at compile time). Google is your friend.
I have a CustomControl B, which uses a DataContext/MVVM (viewModelB). Now I want to bind one Property of my CustomControl to another control A (uses viewModelA as DataContext).
So I have two Ideas:
Whenever PropA in viewModelA changes, I could directly update PropB in the viewModelB. But this creates a dependency between the viewModels, which seems ugly to me. Or is this a common way in the MVVM pattern and can't be avoided?
As an alternative I could think of a dependency property on CustomControlB and wire it to CustomControlA's viewModel by a binding, something like that:
<myControlB PropB={Binding ElementName=myControlA, Path=DataContext.PropA} />.
So far so good, but the dependency property is defined on the view now. How should I visualize it?
a) Should I transfer the value (from the property wrapper) to viewModelB and bind to it from viewB's XAML code?
b) Or should I directly update the view from B's codeBehind? Would this be still a proper MVVM "style"?
Which of the options would you recommend?
regards
Andreas
As long as ViewModelA doesn't actively update ViewModelB, there is no real coupling between the two viewmodels. What I mean is that if your main view model (which knows both viewmodels) is the one that wires up the binding, the view models are still loosely coupled.
So to me any of these are fine:
Bind directly to myControlA.DataContext.PropA from XAML
Have the MainViewModel register for ViewModelA's property changed event and modify ViewModelB's property as necessary. Here MainViewModel knows about the two view models, but they know nothing of each other.
I am starting with a new project based on MVVM approach.I will be loading some data asynchronously from some web service.I am confused about where to implement this INotifyPropertyChanged interface,in a viewmodel,model or both.
Also If I implement INotifyPropertyChanged on a model(let's call it ModelA).Then I create an ObservableCollection<ModelA>,Will not it be redundant as ObservableCollection itself keeps track of any data change made to the list?
ObservableCollection class only updates UI in case of following operations:
Item is added in collection.
Item is deleted from collection.
Collection is clear.
But if any property changes in underlying item i.e. ModelA in your case, it won't be reflected on UI unless your Model class is implementing INotifyPropertyChanged interface and raising PropertyChanged event on property change.
So, as a thumb rule you should implement INPC both at your ViewModel layer and also at Model layer.
Practically you need to implement INotifyPropertyChanged to objects which property will be displayed in UI using data binding. If you bind the UI directly to property of your model then you need to implement it in the model too.
ObservableCollection only notify UI when object added or removed from collection. To get the UI notified when property of one or more objects in that ObservableCollection changed you still need to implement INotifyPropertyChanged in that object class.
The answer is simple. If you need your model to implement INotifyPropertyChanged then it should. Redundant or not if you need to keep track on a single property you will be better of using that event rather than the ObservableCollection.
I guess I am still a little hazy on how communication goes in MVVM. I read that you are not supposed to use events to communicate with the viewmodel, so i assume that you send a command.
However, commands actually bubble up within the visual tree (the view), right? so then it may reach some target control that can handle the command. Does that target control then have a viewmodel that can modify the model?
Sorry, I'm really confused about how to get commands from the view to the model. I assume that getting information the other way is just a simple matter of having the model implement Inotifypropertychanged to tell the viewmodel that it has changed and then have the viewmodel implement inotifypropertychanged so that the view can bind to the viewmodel and have the properties update.
http://blogs.msdn.com/blogfiles/erwinvandervalk/WindowsLiveWriter/ImplementingtheModelViewViewModelpattern_D996/image_14.png
Not all commands bubble - those are RoutedUICommands, which are just a particular implementation of the ICommand interface provided by the framework. You can implement your own ICommand objects that have custom behavior and act just like normal objects (no bubbling, tunneling). If you create them in your ViewModel, certain View objects like Buttons and MenuItems can bind directly to them through their 'Command' properties.
I am new to WPF/MVVM and the examples I have found do not seem to cover an issue I am facing.
I have a screen for managing a rather complex business configuration object. In MVVM I think this means I should have the following:
A XAML View with close to zero logic
A ViewModel class that has the screen logic
My usual business classes fill the role of Model and have all business logic
In my situation there are business rules that say changes to fieldA of my business class might have various side effects, for example changing the value of fieldB, or populating an entire list of sub-objects.
I could be wrong, but I think I should keep these rules encapsulated in the business class, as these rules are not really about the screen so much as the entity.
Naturally, these side-effects need to make their way back onto the screen immediately.
So from the user's perspective, he might edit fieldA, and see fieldB updated on the View.
I understand how to databind from the View to the ViewModel.
But in my case, it seems that I need two layers of databinding: one between the View and ViewModel, and another between the ViewModel and the Model.
Given that I have essentially the same problem twice, I think one solution should apply. So I have made my Model class into a DependencyObject, and I have made its properties into DependencyProperties.
Looking at fieldA for example, it would appear in all three layers:
View as a visual component databound to ViewModel.FieldA, for example text="{Binding FieldA, Mode=TwoWay}"
ViewModel as a DependencyProperty bound "upward" to the View, and "downward" to the Model
Model as a DependencyProperty
I prefer not to directly couple my View XAML to the business object by skipping part #2, this does not seem like a clean application of the pattern to me. Perhaps that is misguided.
I essentially seem to need a "pass-through DependencyProperty" in my ViewModel.
My questions:
Is this the right general approach or am I thinking about it all wrong?
Are there examples out there using this pass-through approach?
Can someone give a code example of the proper way to create a pass-through binding between the ViewModel and Model FieldA DependencyProperties?
I struggled with this issue myself, and I imagine it is a very common snag when it comes to MVVM. My answer was to avoid polluting the domain with DependencyObject or INotifyPropertyChanged as it somewhat negates the validity of using a ViewModel.
The goal of a ViewModel is to expose a model in a manner that is relevant to a particular view. It gets confusing when the VM essentially needs to expose an entire domain object. I refer to these as "Editor" view models. These are the most tempting to pass through properties from the domain object. In these cases I give the VM a reference to a domain object (composition) and pass through getters and setters. The ViewModel adopts INotifyPropertyChanged and IDataErrorInfo rather than DependencyProperty to signal the UI if the UI needs to refresh or display validation errors. If the domain raises a validation error, then the VM catches it and prepares it into the data error info details for the view.
I would agree with Steve that you should avoid using DependencyObject and DependencyProperty in your model/domain classes, and the view model classes should adopt INotifyPropertyChanged and IDataErrorInfo for binding purposes.
I would add that in your view model classes, I would avoid using DependencyProperty except for properties that you need to utilize in xaml logic, such as DataTriggers.
For handling changes that are triggered within a model layer class, I would also have a reference to the model/domain object in the view model class, and pass through getters and setters to the model/domain class just as Steve mentioned. I would add that the model/domain class will need to raise an event that the view model class will need to subscribe to, so that OnPropertyChanged() for one or more properties can be called in your view model class based on a change that happened in your business logic.
Firstly, I would not recommend using dependency properties (DP) for view models, or models. DPs are properties that have been designed with UI concepts in mind, such as precedence rules, DataContext support, default values and more. You do not need these concepts within a view models, so you should use INotifyPropertyChanged instead.
Having a view-model that is simply a pass-through to a model layer adds no value at all. So don't do it! You should never add layers, structures or concepts to your code just because you think you should. Simplicity is something that you should always strive for.
So, if you can implement a model layer, with INotifyPropertyChanged simply bind that to your view.
However ... in some cases you may not be able to implement INotifyPropertyChanged in your model. It might be generated from a web service for example. In this case you will need a view model that performs pass-through functionality, but also adds change notification via INotifyPropertyChanged.