Update observable collection by requerying or adding to collection? - wpf

I have a observable collection exposed as a property within a view model. The observable collection is loaded with objects from a data access layer (linq2sql).
When a new item is added to the database through another view model what is the best way to update the observable collection? Should I repopulate the observable collection with a query to the database or directly insert the new object into the collection?
Also I am still trying to work out how to get one view model to communicate with another one, but I've only been using mvvm for 3 days.

You can use a whole new class to manage notifications from one class to another. For the question regarding whether to load all entities or just add newly added entity, it really depends on the number of possible entities to load each time. If they are going to be very few, you can reload them each time, otherwise just add the newly added object to the collection.
Example:
class ViewModel1
{
ObservableCollection<Object> entities;
public ViewModel1()
{
EventsManager.ObjectAddedEvent += new EventHandler<ObjectAddedEventArgs>(EventsManager_ObjectAddedEvent);
entities = new ObservableCollection<Object>();
}
void EventsManager_ObjectAddedEvent(object sender, ObjectAddedEventArgs e)
{
entities.Add(e.ObjectAdded);
}
}
class EventsManager
{
public static event EventHandler<ObjectAddedEventArgs> ObjectAddedEvent;
public static void RaiseObjectAddedEvent(Object objectAdded)
{
EventHandler<ObjectAddedEventArgs> temp = ObjectAddedEvent;
if (temp != null)
{
temp(null, new ObjectAddedEventArgs(objectAdded));
}
}
}
class ObjectAddedEventArgs : EventArgs
{
public Object ObjectAdded { get; protected set; }
public ObjectAddedEventArgs(Object objectAdded)
{
ObjectAdded = objectAdded;
}
}
class ViewModel2
{
public void AddObject(Object o)
{
EventsManager.RaiseObjectAddedEvent(o);
}
}

Whenever a model object is saved into the database, send a message to the viewmodels including the saved model object. This could be achieved using the Messenger helper class in MVVM Light Toolkit

As for the second part (how to teach view models talk to each other) I prefer to keep view models as decoupled as possible. Thus Event Aggregation or some kind of Message Broker seems to be natural choice.
The first part of the question is bit trickier, and I don't know correct answer. If Observable collection contains thousands of items I would try to choose an approach that doesn't involve complete reconstruction. Otherwise try the simplest and easiest solution you can come up with.

I use libraries I created that effectively allow one DataContext to save changes back to a parent DataContext and for a parent DataContext to notify its children that it just received changes.
With this functionality, I create a single master DataContext for my whole application, then for any modal windows with Ok and Cancel buttons or other parts of the UI that temporarily need their own "view of reality" I create child DataContexts. When the child DataContext writes back to the parent this causes all controls bound to objects in the parent to update and for the parent to broadcast the changes to all children so they can update too (or not, if they are in snapshot mode).
This solution took a while to code but works beautifully. I also use exactly the same mechanism to send changes to a parent DataContext on the server which is shared by other clients, so everyone has up-to-date data and giving me great caching performance. I even use it for communicating with my back-end data store.

Related

Correct way to handle commands that rely on multiple view models

I'm relatively new to WPF and MVVM and i am trying to understand how to use commands correctly when they have dependencies in more than 1 view model.
A couple of examples:
In my current application i have a RelayCommand which causes a save action to occur in a couple of different view models (they write a couple of different files). Currently i am handling this using a the mvvmlight messenger to send a message to those view models to get them to do the save which i think is the correct way to do it as it avoids having to provide some kind of delegate or event to/on those view models.
I have a RelayCommand in a view model that has a CanExecute method which relies on the state of 2 other view models. I've currently handled this via the mvvmlight messenger as well by having changes in the view models the CanExecute method depends on message that their state is now valid for the operation. This seems messy but the only alternative i could think of was to use a delegate or event effectively weaving the view models together which i believe i should be avoiding.
Is there some generally accepted way to deal with this which i am missing?
In general your view model layer should have a 1:1 relationship with your view, there should be no good reason for a "Save" function to exist in a view model which is then called by another view model.
What it sounds like you should be doing is putting that logic into a service i.e. something like this:
public interface ISerializationService
{
void Save(SomeData data);
}
Then you need an implementation for this service that does the actual work:
public class SerializationService : ISerializationService
{
void Save(SomeData data)
{
// actual save happens here
}
}
Your view models should then contain properties that point to instances of these services:
public class MyViewModel : ViewModelBase
{
[Inject]
public ISerializationService SerializationService { get; set; }
// called when the user clicks a button or something
private void ButtonClickCommand()
{
this.SerializationService.Save(this.SomeData);
}
}
The only question remaining is "What sets the value of SerializationService?", and for that you need a dependency injection framework. There are plenty out there, MVVMLight installs one itself, but Ninject is the de-facto standard. When implemented properly the injection framework will create all view models for you and then "inject" the dependencies, i.e. your SerializationService property, of type ISerializationService, will be initialized with an instance of your SerializationService class (which in a case like this will also be configured to be a singleton).
Dependency Injection takes a bit of work to get your head around but once you start using it you'll never look back. It facilitates complete separation-of-concerns whilst alleviating the need to pass pointers to everything all up and down your architectural hierarchy.

WPF MVVM: an issue of organising ViewModels

what I think I face is a problem of design - one I assume has been solved many times by many people since it seems like it would be very common.
I'm using WPF with XAML and a simple MVVM approach, for the record.
My intention is to create a TreeView, using the MVVM design pattern in WPF.
I have a data model which contains two classes: Scene and Character. Each Scene contains many Characters.
I have created a CharacterViewModel, which is fairly simple (and works fine). Naturally this wraps around the existing Character class.
The Scene class is where I'm getting confused. As I understand it, the SceneViewModel should wrap around the Scene class, just as the CharacterViewModel did for the Character class. But the difference is that Scene contains a list of Characters and thus adds exta complications.
The two options seem to be as follows:
Option 1: Scene contains List of Character and so SceneViewModel also will have that as part of it.
Option 2: Scene contains List of CharacterViewModel and so SceneViewModel will also have that as part of it.
I'm not sure which one to go for to be honest. I suspect it's the second (and this tutorial seems to agree (example 6 is the heading for the section I'm referring to). The first option seems like it would make things really weird (and also why created the CharacterViewModel at all?) but the second seems strange because it seems to muddy the waters regarding what should be in the model part of the program and what should be in the view model part of the program.
I hope I've explained my problem and I also hope someone can offer some help.
Thanks.
Let me first address this statement:
...the SceneViewModel should wrap around the Scene class, just as the CharacterViewModel did for the Character class.
This isn't exactly true. View model should be created for each view. There may be a one-to-one with your model classes, but that isn't a strict part of the MVVM idea. One view may need to present data from multiple "root" model elements (model elements that don't have an explicit relationship like the parent-child relationship in your application), or you may need to have multiple views for a single model element. And to elaborate further, each view model should ideally be isolated from the view technology as much as possible (i.e. a single view model is sufficient to create a WinForms view or a WPF view or an HTML view, etc).
For example, you may have a view that displays data from your Scene class. That view may also display some data for each Character in your Scene. The user may be able to click on a Character and open a view just for that Character (e.g. a popup). In this case, there may be separate view models to represent the Character in the root view and the popup. I tend to name my view model classes according to the root of the view. For an application like yours, I would have something like SceneViewModel and SceneCharacterViewModel (or SceneViewModel_Character, or CharacterInSceneViewModel -- any of these names conveys that the class is for representing a Character in a view for a Scene). This would differentiate that view model from the popup view (which would be Character-centric and would be named something like CharacterViewModel (or even CharacterDialogViewModel or CharacterPopupViewModel or CharacterEditorViewModel).
Keeping collections in sync between the model and view model is annoying but often necessary. Not always necessary, mind you -- there will be cases in which you'll find there are no additional view-model features that you need to add to a model, so it's perfectly acceptable for the view to reference the model directly in this case.
An example of keeping a model collection and view model collection in sync: Suppose your root SceneView has a button for each Character. That button will display a popup for the Character. Suppose further that the Character popup doesn't have a similar button because then it would allow the popup to open another popup (etc). You may want to use an ICommand implementation so that you can just bind the button to the command. It's definitely not appropriate for the ICommand instance to be in the model (even though the command may call a public method on the model). The appropriate place for this would be in the view model for the Character in the Scene view (not the view model for the Character in the popup). For every Character in the model, you would need to create a view model that references the Character and stores additional view-model stuff (the ICommand object).
This means that, as Characters are added/removed from the Scene, you need to create view models specifically for those Characters within the Scene view model. I would typically do this:
At construction time (or whatever time the view model initially receives the model), create a view model for each child object. Put those view models into a public property with a type of something like ReadOnlyCollection<SceneCharacterViewModel>. Your view will bind to that collection.
As child objects are added to the model (either internally or through a public method on the model), the model should notify the view model in an appropriate way. Since the model shouldn't have a direct reference to the view model (not even through an interface -- a model should be completely functional even in a non-UI context, in which there is no view model), the most appropriate way is to use events. You can do this a couple of ways:
Expose events from your model like CharacterAdded, CharacterRemoved or even CharactersUpdated (the last of these would be able to communicate either an add or a remove using a single event)
ObservableCollections (or ReadOnlyObservableCollections), which are most commonly used in view models, can also be used in models, in which case all the events are already available to you. The downside to this is that processing the events off of these collection types isn't the easiest thing.
A third option that is totally different: If your view model or command instance is directly invoking a method like sceneModel.AddCharacter(newCharacterModel), then you can just update your view model immediately after this line without needing any events. I often find myself starting this way because it's simple, but I almost always end up using one of the previous two techniques instead, as those techniques allow the model to notify the view model even in cases where the update is happening internally (e.g., in response to a timed event or asynchronous operation that is controlled by the model).
All of that being said, here's what a "pure" MVVM architecture would look like for your application. Purity can come at the expense of simplicity, so sometimes it's better to take some shortcuts here and there. One common shortcut: In WPF, it's often easier just to put all of your child widget content in the ItemTemplate of the ItemsControl that is being used to diplay your children, rather than creating a separate UserControl for the children.
I guess from your explanation Scene is the Model and SceneViewModel would wrap additional view related functionality to your model in the view model. Same applies for CharacterViewModel.
Whatever your view needs to display you would have a SceneViewModel with a list of CharacterViewodel or vice versa. Or like mentioned your could build up a tree structure with your ViewModels.
My personal view of things is, it is important to stay in the ViewModel universe. So when your construct a view model you would inject your model via a service and build up your ViewModel and only have lists with view models. You would need to do some mapping but there are useful frameworks like automapper, etc already available. But remember there are no hard rules with MVVM.
I didn't understand your choices, However, I think you just need one View Model and it should contain an ObservableCollection of the Scenes. I name it SceneViewModel:
public class SceneViewModel
{
public SceneViewModel()
{
Scene m1 = new Scene() { Name = "Scene1", Characters = new ObservableCollection<Character>() { new Character() { Name="C1" }, new Character() { Name = "C2" } } };
Scene m2 = new Scene() { Name = "Scene2", Characters = new ObservableCollection<Character>() { new Character() { Name = "D1" }, new Character() { Name = "D2" } } };
Scene m3 = new Scene() { Name = "Scene3", Characters = new ObservableCollection<Character>() { new Character() { Name = "R1" }, new Character() { Name = "R2" } } };
_scenes = new ObservableCollection<Scene>() { m1, m2, m3 };
}
ObservableCollection<Scene> _scenes;
public ObservableCollection<Scene> Scenes { get { return _scenes; } set { _scenes = value; } }
}
Scene will have an ObservableCollection of Characters
public class Scene : INotifyPropertyChanged
{
ObservableCollection<Character> _characters;
public ObservableCollection<Character> Characters { get { return _characters; } set { _characters = value; RaisePropertyChanged("Characters"); } }
string _name;
public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
and at last, Character:
public class Character : INotifyPropertyChanged
{
string _name;
public string Name { get { return _name; } set { _name = value; RaisePropertyChanged("Name"); } }
public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propname)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propname));
}
}
View
<TreeView DataContext="{Binding}" ItemsSource="{Binding Scenes}">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate ItemsSource="{Binding Path=Characters}">
<TextBlock Text="{Binding Path=Name}"></TextBlock>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Name}"></TextBlock>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
public MainWindow()
{
InitializeComponent();
DataContext = new SceneViewModel();
}

WPF MVVM OnPropertyChanged Two ViewModels Communication

I have a WPF app that uses a business object called Visit, it has a lot of child objects like patient, exam, and others. There are views and view models for editing these various child objects, so there is a view and view model for editing patient info and one set for exam info, etc. There is also a main window view model.
When I need to open a new Visit, I have a search screen that also has it's own view model. It needs to open new visit from the database and notify all the other views that the visit has changed.
I've looked into WeakEventManager, and also having one view model that is the parent of all the others, but I'm not sure what is the best way to proceed. I'd like to know what the relationship between the view models should be and how the open/search view model should tell all the other views to update. I have been calling OnPropertyChanged("propname") in my view models when a property is updated, but since the other views don't know about the open/search view model, they don't care if I say OnPropertyChanged("Visit")
Have a look at this post on SO that talks about the Messenger. In your case you case post the Visit object and have the ViewModel capture that for display.
If you have a very data centric views where the Model data is pretty much presented directly on the View without a lot of modification you can easily expose the Model as a property on the ViewModel and have the View bind to its properties.
This way when one View updates the Model the other View's will update automatically without having to listen for property change events on the Model
Edit:
To elaborate on my second point: You may or may not need this but if your Model also implements INotifyPropertyChanged then any changes to that model will be propagated to the View automatically.
If you need to have 2 Views with the Visit object then you can have the Visit property directly bound in XAML
public class ViewModel1 : ViewModelBase
{
public ViewModel1(IMessenger messenger)
{
messenger.Register<Visit>(this, (v) => CurrentVisit = v);
}
public Visit CurrentVisit
{
get { _visit; }
set { _visit = value; RaiseNotifyPropertyChange("CurrentVisit"); }
}
}
public class ViewModel2: ViewModelBase
{
public ViewModel2(IMessenger messenger)
{
messenger.Register<Visit>(this, (v) => CurrentVisit = v);
}
public Visit CurrentVisit
{
get { _visit; }
set { _visit = value; RaiseNotifyPropertyChange("CurrentVisit"); }
}
}
public class CurrentVisit : INotifyPropertyChanged
{ ... }
Like I said this is only applicable if you need the same Visit object shared amounst 2 or more ViewModels and if the View's mostly are data centric or in other words the data from the Model is being presented directly on the screen. This is to avoid duplicating the properties in the ViewModels and having to raise the property change event all the time.
use global variable. simply use a Property in your base ViewModel class whose set part set the global variable and get part return that variable value... for setting that global variable create a class in other common project and create a static public variable or property.

WPF DataGrid Add, Update and Delete using MVVM

I am looking for a sample code/Article which would demonstrate WPF DataGrid in action with MVVM pattern to add, updated and delete record from database.
I have a specific requirement for allowing user to insert new record using DataGrid not a new child form.
If anyone can recommend good resource or provide a sample for that particular task it would be great help for me.
Here on CodeProject is an article about WPF DataGrid + MVVM pattern:
http://www.codeproject.com/KB/WPF/MVVM_DataGrid.aspx
I don't know of any good articles on the subject, but I don't see the problem; as long as you bind to an ObservableCollection or ListCollectionView containing objects whose class has a default constructor (I don't think there are other restrictions), the DataGrid will handle things pretty well. The collection you bind to must have some way of adding new items, which is why you need to bind to an ICollection or IEditableCollectionView - the latter is preferred, as it has specific options for controlling the creation of items - see AddNew, CanAddNew etc, which the DataGrid works well with.
Edit:Pasted the part, which fits your question.
Full article: http://www.codeproject.com/Articles/30905/WPF-DataGrid-Practical-Examples
This example demonstrates how to use a DataGrid to perform CRUD operations via binding where the database integration is decoupled via a Data Access Layer (DAL).
The Architecture
This example is a simple CRUD application which allows the user to edit items in the Customers table of the Northwind database. The example has a Data Access Layer, which exposes Find/ Delete/Update methods that operate on simple data objects, and a Presentation Layer that adapts these objects in such a way that they can be bound effectively by the WPF Framework. Because we are only performing CRUD functions, I have not added a Business Logic Layer (BLL); if you are a purist, you could add a pass-through BLL; however, I feel it would add little to this example.
The key classes within this architecture are shown below:
The Data Access Layer exposes an interface for managing the lifecycle of the Customer Data Objects. The class which implements this interface uses a typed DataSet as a database integration layer; however, this is hidden from the clients of the DAL. The presence of this layer means that we are not directly coupled to the database schema or the generated dataset schema, i.e., we can change our schema, yet still provide the interface given below to our clients:
public interface ICustomerDataAccessLayer
{
/// Return all the persistent customers
List<CustomerDataObject> GetCustomers();
/// Updates or adds the given customer
void UpdateCustomer(CustomerDataObject customer);
/// Delete the given customer
void DeleteCustomer(CustomerDataObject customer);
}
public class CustomerDataObject
{
public string ID { get; set; }
public string CompanyName { get; set; }
public string ContactName { get; set; }
}
As you can see, there are no UI framework specific interfaces or classes (such as ObservableCollection) exposed by the DAL. The problem here is how to bind the customers returned by ICustomerDataAccess.GetCustomers to our DataGrid and ensure that changes are synchronised with the database.
We could bind the DataGrid directly to our customer collection, List; however, we need to ensure that the UpdateCustomer and DeleteCustomer methods on our DAL interface are invoked at the appropriate points in time. One approach that we might take is to handle the events / commands exposed by the DataGrid in order to determine what action it has just performed or intends to perform on the bound customer collection. However, in doing so, we would be writing integration code that is specific to the DataGrid. What if we wanted to change the UI to present a ListView and a number of TextBoxes (details view)? We would have to re-write this logic. Also, none of the DataGrid events quite fit what we want. There are "Ending" events, but no "Ended" events; therefore, the data visible to event handlers is not in its committed state. A better approach would be if we could adapt our collection of Customer objects in such a way that they could be bound to any suitable WPF UI control, with add/edit/remove operations synchronised with the database via our DAL.
Handling Delete Operations
The ObservableCollection class is a good candidate for our data binding needs. It exposes a CollectionChanged event which is fired whenever items are added or removed from the collection. If we copy our customer data into an ObservableCollection and bind this to the DataGrid, we can handle the CollectionChanged event and perform the required operation on the DAL. The following code snippet shows how the CustomerObjectDataProvider (which is defined as an ObjectDataProvider in the XAML) constructs an ObservableCollection of CustomerUIObjects. These UI objects simply wrap their data object counterparts in order to expose the same properties.
public CustomerObjectDataProvider()
{
dataAccessLayer = new CustomerDataAccessLayer();
}
public CustomerUIObjects GetCustomers()
{
// populate our list of customers from the data access layer
CustomerUIObjects customers = new CustomerUIObjects();
List<CustomerDataObject> customerDataObjects = dataAccessLayer.GetCustomers();
foreach (CustomerDataObject customerDataObject in customerDataObjects)
{
// create a business object from each data object
customers.Add(new CustomerUIObject(customerDataObject));
}
customers.CollectionChanged += new
NotifyCollectionChangedEventHandler(CustomersCollectionChanged);
return customers;
}
void CustomersCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.Action == NotifyCollectionChangedAction.Remove)
{
foreach (object item in e.OldItems)
{
CustomerUIObject customerObject = item as CustomerUIObject;
// use the data access layer to delete the wrapped data object
dataAccessLayer.DeleteCustomer(customerObject.GetDataObject());
}
}
}
When a user deletes a row with the DataGrid control, the CollectionChanged event is fired on the bound collection. In the event handler, we invoke the DAL DeleteCustomer method with the wrapped data object passed as the parameter.
Handling delete operations is relatively straightforward, but how about updates or insertions? You might think that the same approach can be used, the NotifyCollectionChangedEventArgs.Action property does include Add operations; however, this event is not fired when the items within the collection are updated. Furthermore, when a user adds a new item to the DataGrid, the object is initially added to the bound collection in a non-initialized state, so we would only ever see the object with its default property values. What we really need to do is determine when the user finishes editing an item in the grid.
Handling Updates / Inserts
To determine when a user finishes editing a bound item, we need to delve a little deeper into the binding mechanism itself. The DataGrid is able to perform an atomic commit of the row which is currently being edited; this is made possible if the bound items implement the IEditableObject interface which exposes BeginEdit, EndEdit, and CancelEdit methods. Typically, an object implementing this interface would return to its state at the point when the BeginEdit method was called as a response to the CancelEdit method being invoked. However, in this instance, we are not really concerned about being able to cancel edits; all we really need to know is when the user has finished editing a row. This is indicted when the DataGrid invokes EndEdit on our bound item.
In order to notify the CustomerDataObjectProvider that EndEdit has been invoked on one of the objects in the bound collection, the CustomerUIObject implements IEditableObject as follows:
public delegate void ItemEndEditEventHandler(IEditableObject sender);
public event ItemEndEditEventHandler ItemEndEdit;
#region IEditableObject Members
public void BeginEdit() {}
public void CancelEdit() {}
public void EndEdit()
{
if (ItemEndEdit != null)
{
ItemEndEdit(this);
}
}
#endregion
When items are added to the CustomerUIObjects collection, this event is handled for all the items in the collection, with the handler simply forwarding the event:
public class CustomerUIObjects : ObservableCollection<CustomerDataObject>
{
protected override void InsertItem(int index, CustomerUIObject item)
{
base.InsertItem(index, item);
// handle any EndEdit events relating to this item
item.ItemEndEdit += new ItemEndEditEventHandler(ItemEndEditHandler);
}
void ItemEndEditHandler(IEditableObject sender)
{
// simply forward any EndEdit events
if (ItemEndEdit != null)
{
ItemEndEdit(sender);
}
}
public event ItemEndEditEventHandler ItemEndEdit;
}
The CustomerObjectDataProvider can now handle this event to receive the notification of CommitEdit being invoked on any of the bound items. It can then invoke the DAL methods to synchronise the database state:
public CustomerUIObjects GetCustomers()
{
// populate our list of customers from the data access layer
CustomerUIObjects customers = new CustomerUIObjects();
List<CustomerDataObject> customerDataObjects = dataAccessLayer.GetCustomers();
foreach (CustomerDataObject customerDataObject in customerDataObjects)
{
// create a business object from each data object
customers.Add(new CustomerUIObject(customerDataObject));
}
customers.ItemEndEdit += new ItemEndEditEventHandler(CustomersItemEndEdit);
customers.CollectionChanged += new
NotifyCollectionChangedEventHandler(CustomersCollectionChanged);
return customers;
}
void CustomersItemEndEdit(IEditableObject sender)
{
CustomerUIObject customerObject = sender as CustomerUIObject;
// use the data access layer to update the wrapped data object
dataAccessLayer.UpdateCustomer(customerObject.GetDataObject());
}
The above code will handle both insert and update operations.
In conclusion, this method adapts the data items and collection provided by the DAL into UI items and collections which are more appropriate for data binding within the WPF Framework. All database synchronisation logic is performed by handling event from this bound collection; therefore, there is no WPF DataGrid specific code.

Why ObservableCollection is not updated on items change?

I noticed that ObservableCollection in WPF reflects changes in GUI only by adding or removing an item in the list, but not by editing it.
That means that I have to write my custom class MyObservableCollection instead.
What is the reason for this behaviour?
Thanks
The ObservableCollection has no way of knowing if you make changes to the objects it contains - if you want to be notified when those objects change then you have to make those objects observable as well (for example by having those objects implement INotifyPropertyChanged)
another way of achieving this would be that you implement a new XXXViewModel class that derives from DependencyObject and you put this one in the ObservableCollection.
for this look at this very good MVVM introduction: http://blog.lab49.com/archives/2650
an example for such a class would be:
public class EntryViewModel : DependencyObject
{
private Entry _entry;
public EntryViewModel(Entry e)
{
_entry = e;
SetProperties(e);
}
private void SetProperties(Entry value)
{
this.Id = value.Id;
this.Title = value.Title;
this.CreationTimestamp = value.CreationTimestamp;
this.LastUpdateTimestamp = value.LastUpdateTimestamp;
this.Flag = value.Flag;
this.Body = value.Body;
}
public Entry Entry
{
get {
SyncBackProperties();
return this._entry;
}
}
public Int64 Id
{
get { return (Int64)GetValue(IdProperty); }
set { SetValue(IdProperty, value); }
}
// Using a DependencyProperty as the backing store for Id. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IdProperty =
DependencyProperty.Register("Id", typeof(Int64), typeof(EntryViewModel), new UIPropertyMetadata(new Int64()));
}}
important things here:
- it derives from DependencyObject
- it operates with DependencyProperties to support WPFs databinding
br
sargola
You can register a method in the view model class aginst the PropertyChanged event of data class objects and listen to them in View model when any change in the property of the data objects happen. This is very easy and straight way to have the control in View model when the items of an observable collection changes. Hope this helps...
Probably because items have no way to alert the collection when they are edited - i.e. they might not be observable. Other classes would have similar behavior - no way to alert you to a every change in the graph of referenced classes.
As a work-around, you could extract the object from the collection and then reinsert it after you are done processing. Depending on your requirements and concurrency model, this could just make the program ugly, though. This is a quick hack, and not suitable for anything that requires quality.
Instead, you could implement the collection with an update method that specifically triggers the ContentChanged (not sure about the name) event. It's not pretty, but it is at least quite easy to deal with.
Ideally, as kragen2uk says, it would be best to make the objects observable and keep your client code clean and simple.
see also this question.

Resources