Notify PropertyChanged on ClearChanges/Refresh - wpf

I want my UI that is basically purely built on data-binding to refresh when I call ClearChange() or Refresh(RefreshMode.OverwriteChangesFromStore,obj). However it looks like the backing fields are used directly by DataAccess instead of the properties they are backing as the setters are not accessed yet the object's properties do indeed get reverted back.
Is there a way to tell DataAccess to use the properties instead so PropertyChanged is called within the setter?
Possibly any other solution? Nothing efficient comes to my mind

Related

Unity container view model communication

What i did
I have HomeViewModel and SellsViewModel.
In the HomeViewModel, I have property "SellID"
In the constructor of SellViewModel, i am able to Resolve reference of HomeViewModel and stored it in m_objHomeViewModel variable in SellViewModel
In the XAML of SellViewModel, i have a textbox which shows "SellID", this textbox is bound to "m_objHomeViewModel.SellID"
What i am getting doing this
Doing this, whenever user selects difference "Sell" on HomeViewModel, automatically my SellViewModel picks it up and shows changes in SellView.
Question
As XAML textbox in SellView is bound to a property in HomeViewModel, changes are getting reflected on UI immediately
But i am not able catch any event (Such as property change) in SellViewModel, catching such event i want to load other values for the selected "SellID" from database.
I am not using Event Agreegator. If used, i can easily subscribed to event in SellViewModel published by HomeViewModel
Q1: How to do it without using Event Agreegator?
Q2: If in XAML, TextBox is bound to property m_objHomeViewModel.SellID, will it create memory leakage?
Q3: If in the HomeViewModel, i get reference to SellViewModel (Using container.resolve) and call a public property or method of SellViewModel whenever "SellID" property in HomeViewModel is modified. Is it a good programming practice? Here i think it will create tight coupling between HomeViewModel and SellViewModel
Please suggest on this...
Regards
A1: If I understand your design, your SellVM will need to manually subscribe to the PropertyChanged event of your HomeVM. If the SellId property of your HomeVM raises PropertyChanged, then your SellVM will see that and respond accordingly.
A2: Without seeing the entire application, simply databinding to a property won't cause a memory leak. As long as the UI is displayed, the HomeVM will be in memory, but .NET does a pretty good job of recognizing when it is no longer needed and cleaning up the memory. The answer to this is highly dependent on your overall design, but the simple act of binding the SellID from the HomeVM through the SellVM won't, on its own, cause a memory leak.
A3: This sounds a little strange - Without understanding the full architecture, it seems that the SellID should belong to the SellVM, and when the users switches SellID, the HomeVM loads the SellVM with the appropriate SellID. This seems more OO and allows you to separate concerns. This way everything about the "Sell" (sale?) is encapsulated in the SellVM and the HomeVM is strictly responsible for coordination (loading the correct child VMs). But this is based on what little I can gather about your overall design.

viewmodel have to be public. How should I deal with that?

Pretty much it summarizes my problem here:
Double check - does it ever make sense to have internal viewmodel class?
I have controls.DLL and I'd like to keep this custom control bindings and viewmodel's internal. However, this doesn't seem to be possible.
How do you get around that? The only way I see it - don't use bindings..
Why do you have a view model for a custom control? I assume you're assigning the view model object to the DataContext property, but this is almost always a mistake: the DataContext should be available to consumers to use and abuse as they please. Stated another way, what happens if a consumer of your custom control explicitly sets the DataContext? It sounds like your control will stop working and throw a bunch of xaml binding errors.
A custom control is inherently lookless. There is no model or view model, just a view. That view is the .cs file. You supply a default look via your themes/generic.xaml file, but consumers should be able to supply their own template. If you're tying them to a view model, they also need to know how to create a view model instance and all of its dependencies. You've just created highly coupled code. DI containers can loosen the coupling, but that just downgrades the relationship between classes from "coupled" to "related". I say, why do consumers even need to know that information?
A better approach is to provide all of the properties for your control as dependency properties. Then your generic.xaml can provide a control template that uses the more efficient TemplateBinding to bind properties/objects to your control. If you need to populate these dependency properties from a business object, expose another dependency property of type IBusinessObject and set the derived values in that object's PropertyMetaData changed handler. If your IBusinessObject type contains a property which is yet another class which implements INotifyPropertyChanged, you should probably (1) rethink your object graph or (2) create a Bnding object in code using the subclass.
I think following all of the above advice will eliminate the problem about which you're concerned plus the other problems as well. Leave the view models to the UserControls. And yes, this is why custom controls are a MASSIVE headache. Doing them right is fairly involved.
Try protected internal. I suppose this should work. Although I don't think its good idea to have the ViewModel not public at all, cause one of the purposes of it is to be able to define several Views against the same ViewModel, which may come from different assemblies.

What is the proper way to create a dependency property bindable to an observable collection?

I need to create a dependency property on a custom control. The problem is that the propertyChangedCallback does not get called when the collection changes. How should I properly handle this scenario?
I am afraid of memory leaks caused by simply event hooking to the CollectionChanged event during the initial property change (when the observable collection is assigned to the dependency property).
In other words, I need to create another property like ItemsControl.ItemsSource.
I've looked to the source of ItemsControl.ItemsSource using Reflector. Internally it uses WeakCollectionChangedListener which is internal class. I probably could copy its source and make use of it but i believe there must be another (better) solution.
There is a good in-depth post on Delay's Blog on implementing the WeakEvent pattern in Silverlight for this exact scenario (changing a collection source which implements INotifyCollectionChanged).
He provides code for a WeakEventListener implementation as well.

Possible to use Bindings only for the SourceChanged event?

Basically I want to use the WPF Binding framework to "observe" a property in the data context, and when that value changes to call an event handler. I do not actually want to bind it to any target.
Sounds simple but from what I can see Binding is too coupled (to the visual tree and various other bits) to be able to use it flexibly.
Any thoughts?
You are correct that bindings are associated with the visual tree: they're about hooking UI elements up to data elements. So if you wanted to use a binding for this, you would indeed have to set it on a dummy framework element.
However, if WPF can observe the property then you can too. WPF is just using the data context object's INotifyPropertyChanged interface. So rather than setting up a binding, you can just cast the object you want to observe to INotifyPropertyChanged, and subscribe to its PropertyChanged event. Internally, that's all WPF is doing anyway.
(If you're concerned about lifecycle issues, WPF provides the PropertyChangedEventManager which uses weak references. Call PropertyChangedEventManager(dataObject, listenerObject, "WhateverPropertyYouWant") where listenerObject is the object you want to receive the change notifications.)

Binding to IsolatedStorageFile variable AvailableFreeSpace in Silverlight

I am trying to display a simple text block that shows the value of AvailableFreeSpace from IsolatedStorage.
That is: System.IO.IsolatedStorage.IsolatedStorageFile.GetUserStoreForApplication().AvailableFreeSpace
It needs to dynamically update as the available storage changes.
I know this is probably basic but I can't figure out how to bind to this variable. Any hints?
When you bind a property on a plain old CLR object, like IsolatedStorageFile.AvailableFreeSpace, to a UI property like TextBlock.Text you actually need to do a little extra work to make sure that changes in the CLR property are propagated to the UI. In SL, that means the CLR object (IsolatedStorageFile in this case) needs to implement INotifyPropertyChanged. The implementation is very simple, just add an event to your object called PropertyChanged; then fire that event every time something interesting changes which would be AvailableFreeSpace in your case. Since IsolatedStorageFile doesn't implement INotifyPropertyChanged you won't get updates when the AvailableFreeSpace changes. You'll need to create your own class that implements this interface, then use some mechanism like timer based polling to check IsolatedStorageFile.AvailableFreeSpace on a regular basis and reflect changes in your own AvailableFreeSpace property. Personally I would run all write calls to isolated storage through a custom class that would check the free space after the write operation and report those changes to the class you created with a custom AvailableFreeSpace property, making sure to fire the PropertyChanged event when this happens instead of using a timer to check periodically.

Resources