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.
Related
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
If I have a model which is pretty much a readonly collection and dispayed on a grid, where the user selects a row.
Do I need to have INotifyPropertyChanged always implemented on the model? Is there a performance benefit of implementing vs not?
I would like to know if performance is impacted by UI trying to use something like
var x = Model as INotifyPropertyChanged;
which it wouldn't have used otherwise.
If you are using the model in any data bindings, then yes, you should implement INotifyPropertyChanged even if it is completely immutable. The reason has nothing to do with performance, but to avoid a memory leak.
A Binding will always try to register for change notifications, and if you do not implement INotifyPropertyChanged or expose discrete change events of the form [Property]Changed, it will register through the PropertyDescriptor API. The default, reflection-based PropertyDescriptor implementation uses a global subscription table, and if for some reason the Binding does not unsubscribe cleanly, your view model will be kept alive indefinitely. This is in contrast to the weak event pattern used when bindings subscribe to INotifyPropertyChanged notifications. Bindings at runtime generally clean up after themselves, but the Xaml designer is notorious for leaking under these circumstances, causing your designer process's memory consumption to rise steadily as you work.
If you are just displaying in on a DataGrid and not expecting any UI interaction that'll change the value of the Model then you do not have to implement INPC.
WPF is tied to the INPC mechanism to update the UI from the backing Model. You don't need it if you load it once and won't change again. However, INPC can be pretty handy and you need to implement it if say a business logic that requires you to update something to a different row then you can basically subscribe the other model's PropertyChangedEvent to do something to the other row when a property changed is raised.
There is no performance benefit of implementing it.
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.
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.
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.)