Distinguish UI change to variable from code-behind change - wpf

Like the title says I am trying to architecture into my application a way to distinguish the source of a variable change, either from UI or code-behind.
My problem is that I need to trigger some action after a property changed its value, but I only need to do this when the change comes from the UI because otherwise I don-t want to perform that action. I am having some trouble because, for example when a checkbox(two way binding), changes state, my binded property gets updated and then I use the checked and uncheked events to trigger that action.The problem is that when I change the property in codebehind it also triggers those events and I do not want that. Right now, i am using a flag that enables, or not, the actions at the event handlers but I do not feel that this is a good idea.
Any sugestions or ideas?
I am considering using only one-way binding and control everything my self, using commands.

It looks like you have some confusion between your model and your controller. There shouldn't be any cases where it matters if the a change to the model comes from the user or not. If you want to have something like a confirm message it the user makes the change, then don't bind the view control directly to the model, but have the controller respond to the event.
That way, if the control is changed to be the same as the model, then the change is internal, and no confirm is required, but if the control is changed by the user, then the control state differs from the model, and a confirm can be shown.

Related

Google realtime API OBJECT_CHANGED event fired by (almost) anything happening?

Take a custom realtime object "MyObject" one property of which is an IndexReference referring to a CollaborativeList "MyList". "MyObject" also has a collaborative field property "MyProps" into which I put a json string.
In order to detect changes to "MyProps" I tried the following:
MyObject.addEventListener(gapi.drive.realtime.EventType.OBJECT_CHANGED, dealWithChanges);
However, when I make any change to an object in "MyList", which shouldn't affect the IndexReference in any way, the OBJECT_CHANGED event is fired on "MyObject"
Is this by design? It makes the OBJECT_CHANGED event useless, effectively a "something has changed somewhere" event, but without it there appears no way to detect a change to "MyProps".
Object changed events bubble, so you can listen higher up the tree for anything that is happening lower.
To listen only for changes on collaborative fields within the particular custom object, you want a ValueChangedEvent

Is there any event before source is updated in binding in WPF?

I am looking for something that fire before the source is update
So instead of Binding.SourceUpdated I want Binding.PreviewSourceUpdated
I think you would need to handle this on your UI element and intercept the event if it's not ideal. So for example say you had a text box and a user pressed a key. You would use the PreviewTextInput (or similar preview) to see if you wanted the data changed - then mark the event has handled if you didn't.
The only other option that I know of is to use DataValidation and not allow the property to be updated for the model side.

Is it guaranteed that all the WPF bindings will be functional when OnStartup() is called?

I am working on an application that uses WPF/C# with MVVM. I have one particular ObservableCollection<> which is bound to ListBox.
Scenario 1: When the application is running, I modify this ObservableCollection<> and ListBox is populated as expected.
Scenario 2: With new requirements I have to fill this ListBox by default with some init values. So I have added a method for initializing it in my ViewModel. I call this method in OnStartup() after initializing View & ViewModel. DataContext is also set properly. In this scenario values are updated in the ObservableCollection<>, Unfortunately they are not reflected in the ListBox.
Just to verify if anything is wrong with the OnStartup(), I added the same method call in a callback on ContentRendered from the View, instead of OnStartup() it did work fine.
So my question, When exactly MVVM guarantees that all the bindings are setup correctly?
Edit:
One more observation, if I pop a message/dialog ListBox is populated as expected. It calls ContentRendered callback. And then it populates correctly.
I am almost convinced that ContentRendered should be the function that guarantees the bindings.
I can't say with certainty that this is your issue, without seeing the change to the code, but it sounds like you may now have an initial value of null for the property to which you are binding.
If you subsequently set that property to an ObservableCollection<T>, there is no automatic change notification.
One option would be to raise a notification that the property value changed (from null to something), and then let the ObservableCollection<T> handle change notification from there.
The better solution would be to initialize the property with an empty ObservableCollection<T> from the get-go, then your initialization to default values will mean adding those values and change notification should happen as you expect.
You might get the same problem by starting with a non-null collection, then setting the property to a new instance of a collection, without raising a notification, but I'm not 100 percent certain of that.
If this is not your issue, then I'll be happy to take another look.

How to get an event when WinForms TreeView items gets cleared

I am using a standard TreeView in a WinForms application and everything works fine except for one issue:
Parts of the system need to change depending on the selected TreeNode, which works fine using the AfterSelect event.
However, sometimes the TreeView will get cleared completely resulting in an empty selection which does not trigger this event.
At the momemnt I am calling the event callback manually to fix this issue.
This is obviously dangerous, since I will forget to call this function somewhere. Is there a "correct" way to do this?
Thank You!
This is by design. The underlying native Windows controls only generate notifications for things you cannot figure out yourself. The ListBox control for example doesn't have any event that tells you an item got added or removed. Which is because there is no way for the user to add or remove items. Similarly, there's no way for the user to remove the nodes from a tree view.
These kinds of changes requires code that you write. Since it is your code, you cannot not know that these changes happened. If you want an event then you'll have to raise it yourself. Beware that this is harder than it looks, the TreeNodeCollection class doesn't reliably let you generate an event for programmatic changes to the node collection. It doesn't behave like an ObservableCollection. You are definitely better off by not needing this event.

How to call a user control method using MVVM?

I'm working in a WPF project, I'm using the MVVM patter in my project.
I created a user control (also in WPF) and I want to use it in my project, now, my problem is that I have a method in my user control that I need to call from my View Model, but I don't know how to do that, how to bind to the method inside my control from the view model.
If I use code behind, obviously there is no problem since I have a direct reference to my control, so I can do "mycontrol.MyMethod();"m, but of course, doing in this way will go against the logic of the MVVM pattern.
I tried to use a Dependency Property in my user control, and use that Dependency Property to bind to it in the xaml of my project but it didn't worked, the compiler says that the property was not found or is not serializable.
So I will appreciate if someone can share some light about how can I accomplish this.
Edited
As far as I understand you have the view, which is all the GUI, then you have the model, which is all the logic, and them you have the view-model which is like an intermediate layer used to bind the view with the model, right?
In this way I have developed my project, however I came to the problem that I need a custom control, a TextBox that remember what the user entered, and when he start typing, if there are words that start with that letter, those words are shown as a suggestion, as Google does it.
This TextBox is used as a search filter; so I created a user control to do this, I added a method to my user control to allow whatever application that uses my control to add items to an internal array that holds all the strings that the user has entered.
I created a user control because I couldn't find any control that behaves the way I want.
So my problem is when I add my user control to the main project, because I need to someway be able to call the method that add the items to the internal array, but maybe I'm doing things the wrong way, so if any of you has a better idea, I will appreciate if you shared it with me.
You should never call View methods from ViewModel, and vice versa.
Make a property (ObservableCollection?) on your ViewModel, it will have CollectionChanged event, subscribe to it to monitor changes (if needed).
When you add an item to the collection in your ViewModel, GUI will be updated accordingly (you have to perform the Add() operation on GUI thread, btw).
If you need to change the current position in your list, there are colections for that (CollectionViewSource, etc).
If you really really need to pass a string to your control, make a DependencyProperty and bind it OneWay to your ViewModel's property. When you set the value, it will call PropertyChangedCallback on your DependencyProperty.
Why does the consumer of the user control need to maintain the control's internal array? That seems like you've exposed an implementation detail that you don't need to.
Why not simply make that array a dependency property (and an IEnumerable<string> or ObservableCollection<string> besides)? Then you can simply create the corresponding property in your view model and bind it to the control. It also makes the control considerably more versatile.
You shouldn't call something in the View from the ViewModel since that breaks the model.
If the reason you want to call the method in the user control is to do with UI only, I don't see anything wrong with doing it from the view - the view's cs and the view's xaml are in the same "space" in the model. You can be overly-purist in wanting to have lean and mean view cs files.

Resources