WPF MVVM using LINQ to SQL - wpf

I have binded my customer name textbox to Customer Model and set the mode to two way now I want to update the edited name to database. How can I achieve this ?

Your question is very vague as it doesn't say whether you wanted this on PropertyChanged or when you have a button with either Click event handling or ICommand binding on it.
The decision when to update is totally down to the business model that you are applying. Generally speaking, it's never a good idea to update directly from a PropertyChanged event because it might be a temporary edit and you may wish to update against.
For example, if you have UpdateSourceTrigger=PropertyChanged, then as soon as a character is type, the Property is updated with the new value and if you implmented iNotifyPropertyChanged events, that would instantly fire an update to your database. Because a database connection is transient, usually over a network, it may or may not be available, and it may or may not timeout during a partial update. Thus, you could end up locking up your code or if multi-threading, causing race conditions.
Therefore, it's always better to implement the changes via a save button or when the screen is closed/navigated away from (such as what iOS/Android do).

Related

Accessing ViewModel data in View

I just want to ask if it's OK to access the ViewModel's data in the View backend?
Basically I just need a check to see if a ViewModel's property is set (which gets set when the user selects something), and if it's not I'll just redirect the user to another View telling him he needs to select something first. Is this a poor-design practice or is it OK, just for a minor check like this? Really don't want to implement a static class and extrapolate the data to it, and check it instead.
Another question tightly related to this, is can I call a method from the View (when the View is closing), that unregisters that particular ViewModel from the IoC container (this ViewModel isn't singleton). The alternative is to send a message from the View to the ViewModel when the View is closing, and when the ViewModel gets that message it unregisters itself. The problem I'm trying to solve with this is that, every time that ViewModel is requested it has to be a new one, but my IoC container caches them, making my program a memory hog. All of the ViewModels get released on application exit, meaning x ViewModels will still exist in the cache even though they're most likely not needed.
Basically I just need a check to see if a ViewModel's property is set (which gets set when the user selects something), and if it's not I'll just redirect the user to another View telling him he needs to select something first. Is this a poor-design practice or is it OK, just for a minor check like this?
It does not seem to be wrong to check the value of some ViewModel property and reflect the changes on the View side. The View state could be "bound" to the ViewModel state by the WPF data binding mechanism: Binding, Triggers (Trigger, DataTrigger, EventTrigger), Commands (including EventToCommand), etc.
But sometimes it is useful to handle ViewModel state change by the ViewModel itself using UI Services. For example, IWindowService interface can be introduced to allow to open windows from the context of the ViewModel implementation.
Another question tightly related to this, is can I call a method from the View (when the View is closing), that unregisters that particular ViewModel from the IoC container (this ViewModel isn't singleton).
...
The problem I'm trying to solve with this is that, every time that ViewModel is requested it has to be a new one, but my IoC container caches them, making my program a memory hog. All of the ViewModels get released on application exit, meaning x ViewModels will still exist in the cache even though they're most likely not needed.
It seems to be strange that the described dependency container "cache effect" exists when the registration is specified as "resolve per call behavior" (not "singleton behavior"). Please check that the registration is specified as "resolve per call behavior" (for example, PerResolveLifetimeManager in terms of Unity Container Lifetime Managers).
Update
The ViewModel lifetime problem exists because SimpleIoC container is used.
I would like to recommend using another dependency injection container (with appropriate lifetime management) to make the implementation less complex and error-prone.
But, if there is a strong need to use SimpleIoC container, some kind of the ViewModel lifetime management can be implemented using:
SimpleIoc.Default.GetInstance<ViewModel>(key); method call to resolve an instance of ViewModel;
SimpleIoc.Default.Unregister(key); to un-register the instance when it is no longer needed (Closed event, etc).
The implementation can be found here: answer #1, answer #2.

How to determine if WPF TextBox is dirty (when using UpdateSourceTrigger=LostFocus)

How can I determine when a user has updated the text in a textbox before the Binding has updated the source?
I was expecting to find an "IsDirty" property on either the TextBox or the Binding ...
My problem is that the "Cancel" button Enabled property is bound to the ViewModel's IsDirty property and is disabled until the focus moves out of the textbox.
"IsDirty" needs to be defined as ViewModel.IsDirty || TextBox.IsDirty
WPF can't support the typical IsDirty behaviour that users would expect in a high quality application.
The problem stems from the strange design of the Binder class.
Furthermore WPF architecture is kind of hard-coded to using the default Binder implementation, replacing it is a huge job and requires many "dirty tricks" to work around the endless WPF design flaws.
The easiest way I found to workaround this limitation is to move all value conversion logic to the view model and use UpdateSourceTrigger=PropertyChanged, and implement your own IsDirty and IsInvalid logic and flags.
This approach also plays nicely with Caliburn.Micro
First, why is Cancel disabled? It should be enabled all the time. Any other behavior would be odd. The user should be able to cancel although he hasn't done anything.
Second, I would use Commands so that it can determine whether it can be executed or not based on the state of the viewmodel. Should be easy to implement, if the viewmodel also provide the implementation of the command.
I'd recommend to read some articles and/or tutorials about it. Google for the interface ICommand.
And to answer your question. Assuming you're using binding you could use the INotifyPropertyChanging interface to determine when a value is about to change. You could then store the current value in a backup field or something.
EDIT - Regarding "let him lose data"
Sure it's a valid strategy. Think on a larger input dialog e.g. 5 input controls, which must be validated before persisting the input. I'm assuming that the data is very important according to your arguments. Furthermore, you started to hack your data into the dialog. On input control 3 you decide to press 'ALT + F4'.
First, ask yourself, why did the user press the keys? IMHO he doesn't care about what's happening to his data.
If 'ALT + F4' is just an example for being robust. Forget about it. I think absolute robustness cannot be implemented without being very expensive.
Second, regarding consistency and validity after the restart of the application, you have to throw the data away so that you don't start with an undefined state. Remember, the entity the user began to fill is not valid at this state. Neither the states respectively the values of the properties are.
So IMHO the much better strategy is to restart with a clean and defined state, so that the user is able to continue with whatever you want him to do with your application.
Why is this strategy better? Well, it's much easier to implement. And the much more important argument, the user never gets lost because of an odd state.

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.

Change Tracking View Model: When/How to "Start Tracking"? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I have need of a view model that tracks changes so the user can see things visually change in response to edits and rollback portions. Right now, I "turn on" change tracking as the last step in the constructor for the view model (necessary, because sometimes the view models are constructed from templates or have defaulting logic that triggers PropertyChanged before construction is complete, erroneously leading one to think it's changed even before the user has done anything).
This has worked for the most part,
but with more complicated controls, bindings, and lack of controlling the order for various events in third-party products
and, a need to turn on change tracking after view model is built from a DTO returned from a service call (i.e. the model-model),
is there a better place to turn-on change tracking?
In an ideal MVVM implementation there's neither better nor alternative place, because you aren't likely to know when or how a view communicates with a view model. In fact, a view model shouldn't know anything about a view. A view might be a Silverlight UI or a console app, or a test mock-up, or whatever else. According to general thoughts then, constructor seems to be the only place where 'change tracking' should be disabled.
If you try following the MVVM strictly, you should accept your view models as main objects and views as secondary ones. I mean a view shouldn't introduce any logic that doesn't relate to the specific view implementation. It only displays the current view model state and communicates a user's actions to the view model. If it's true, then you won't need to turn change tracking off wherever except the constructor.
Of course, in the real world this might get rather difficult to follow. If you can't find another solution, you could introduce additional properties to the view model, e.g. IsViewInitialized, which would turn on 'change tracking', and make the view set the property as required.
But you'd better avoid this as long as possible. Such an approach increases coupling between Views and ViewModels which is against one of the main ideas of the MVVM pattern.
If you'd ask me in personal, my view models quite rarely have an alternative logic for the initialization steps and if they do, it's only in the constructors. And I usually don't 'turn off change tracking' but rather set some fields directly to get around the regular change tracking code that for most cases resides in property setters. But sometimes it's more convinient to trigger that logic for some properties even in a constructor.
Generally, there is no "right" or "wrong" place to handle change tracking.
But if you prefer to do it inside VM, your RaisePropertyChanged() method can accumulate list of changed properties (changesList). You should implement public (possibly virtual) method ApplyChanges(), that clears this list and saves data (if you post changes through network, add more checks so you don't send the same data over and over). Also, have public property bool IsChanged { get; }, that returns changesList.Any() -- you can use this property to bind your "Apply" buttons to.
For your case: in complex constructors, invoke ApplyChanges() to reset IsChanged state, and after complex controls are bound to your VM, also invoke ApplyChanges() - even if you know user didnt do anything yet.

TextBox UpdateSourceTrigger = PropertyChanged - does it really affect performance?

The MSDN documentation states:
Bindings that are TwoWay or
OneWayToSource listen for changes in
the target property and propagate them
back to the source. This is known as
updating the source. Usually, these
updates happen whenever the target
property changes. This is fine for
check boxes and other simple controls,
but it is usually not appropriate for
text fields. Updating after every
keystroke can diminish performance and
it denies the user the usual
opportunity to backspace and fix
typing errors before committing to the
new value. Therefore, the default
UpdateSourceTrigger value of the Text
property is LostFocus and not
PropertyChanged.
I understand that in a situation where the update is going directly to a database, or across a network, or if it's an extremely large amount of data, that it could indeed diminish performance to use UpdateSourceTrigger = PropertyChanged on TextBoxes.
But if it is just updating a simple DependencyProperty, or a property of an Entity Framework object (prior to committing), would the performance hit not be negligible?
Just wondering, because I am creating a WPF app which tracks the state of the object being edited and optimizes the Save button appearance depending on whether changes have been made. I thought the easiest way to determine changes would be to catch the relevant SourceUpdated occurences as appropriate. It works optimally when UpdateSourceTrigger = PropertyChanged for the textboxes, as the user gets instant feedback that there are "saveable" changes.
The reason that you're warned about performance degradation is that for the most part, if you need to have the source property updated on every keystroke, it's because you need something to happen when the property's value changes. After all, if you didn't need that "something" to happen, you wouldn't really care when the property got updated, so long as it did eventually.
The real impact on performance depends entirely on what that "something" is. And that's totally dependent on your application. If that "something" is formatting and displaying the value in another TextBlock, doing it on every keystroke probably won't be noticeable. If it's filtering a 10,000-row DataTable and refreshing a DataGrid bound to it, it probably will.
So how do you tell? Well, there are two ways:
1) Understand your application. If you know what the application is doing when you update the source property, you can predict whether or not doing it on every keystroke is going to be a problem. When you say "I guess I was wondering whether it might seem to be fine at first, but can actually cause issues in certain situations I'm not aware of," what you're really saying is, "What happens if I don't know what my application is doing when the user presses a key?"
2) If you don't know what your application is doing when the user presses a key, profile it.
If it is suitable for your application and you don't notice a significant degradation in performance, then there is no problem setting the UpdateSourceTrigger to be PropertyChanged. In fact, if you're using an MVVM framework such as Caliburn.Micro, then it will set this as the default setting for all TextBoxes.

Resources