views:

103

answers:

3

From what I (thought to) understand is that implementing INotifyPropertyChanged within the ModelView, allows to raise the PropertyChanged event in case a property has been modified.

That way the View should get to be notified that the underlying property has changed and hence the UI should fetch the new changes.

Did I get the theory right?

The problem I face is that I have an Infragistics DataGrid bound to a ViewModel. As soon as I change a date Value, I can see how the property on the ViewModel is set correctly and the event is raised. But I haven't subscribed from outside to this event though, how does the UI get notified?

I am asking this because I think the UI is not notofied at all. I have placed a second textbox that is binding thourgh the ViewModel to the same underlying Model property. However if I modify that property with the DataGrid, the TextBox (Mode=OneWay) is not automatically updated.

I actually make use of MVVM-Light Frame work and use ViewModelBase instead of INotifyPropertyChanged and do a RaisePropertyChanged(...). But the result should be similar.

Do I have to subscribe the TextBox manually to that Event somehow?

Edit: I have solved the problem, but dont grasp exactly why this is happening. Before answering the Question I need to explain a bit more about the architecture. The Datgrid is bound to propertyA in ViewModelA that returns an ObservableCollection<ViewModelB>. ViewModelB actually contains all the properties that the Grid should be displaying. All these properties fire in their Setters naturally an OnProperyChanged.

The TextBox was bound to PropertyB, that lives also within ViewModelA. But it returns directly a string, so the underlying getter of PerpertyB returns this:

_cashflowInputs[0].ProjectedDate.ToString();

However if I dont bind the TextBox to this propertyB, but bind it to PropertyA as well, it works:

Its weird. I was expecting it to work the same way. Both Properties live on the same ViewModel and access the same private ObservableCollection<ViewModelB>, why should it matter?

public ObservableCollection<ViewModelB> PropertyA
        {
            get { return _cashflowInputs;}
        }

        public string PropertyB
        {
            get { return _cashflowInputs[0].ProjectedDate.ToString(); }
        }

Kave

A: 

Did you set a binding on your textbox?

<TextBox Text="{Binding Path=PathToMyValue}"/>
Muad'Dib
Yes I did. <TextBox Text="{Binding Test, Mode=OneWay}" />Test is a property on my ViewModel. It shows teh initial value correctly. But when updating the value per DataGrid, I was hoping the TextBox gets updated too. But it doesnt.
Kave
I would be willing to bet that the grid does not do any binding, it just watches the collection for addition/deletion of items. We have had problems with Infragistics datagrid bc it didn't update when values changed and we needed near real-time data updates.
Muad'Dib
+1  A: 

Here's a quick review of how the notification between a data object and the UI element works when the data object implements INotifyPropertyChanged.

1) A property setter on the data object is called to change the property.

2) Within the setter, the data object changes the property value and raises an event to notify any UI elements bound to the data object the property has changed. The event raised will contain the name of the property that was just changed.

3) The UI element handles the event and examines the event arguments to determine which property changed.

4) Now that the UI element knows which property has changed, it calls the appropriate getter to get the up-to-date property value and it updates itself with that value.

So, in your example. If the property 'ProjectedDate' is updated, an event will be raised passing the property name 'ProjectedDate' to the UI element. The UI element will then call the getter of the 'ProjectedDate' property to refresh itself.

The UI element has no idea that 'PropertyB' has changed if an event was never raised with the property name 'PropertyB' as an arguement. Thus, it will not refresh itself with a new value if it is bound to 'PropertyB'. At some point, an event must be raised with the property name 'PropertyB' as an event arguement for an UI element to know it needs to refresh itself with the most up-to-date property value.

ChrisNel52
This perfectly explains it. Thank you very much for clarification. Now I understand why people keep referring to them as Magical Strings. ;)
Kave
A: 

Binding to PropertyB in a control inside a data template in your DataGrid won't work because the data context of the control will be ViewModelB. If you want to bind an element inside a data template to something outside of the data template's context you will need to set its data context to something else, or use element-to-element data binding to bind to something outside of your data template.

Matt Casto
Both controls are inside the same StackGrid, that has its DataContext bound to ViewModelA. Besides I am not using any DataTemplate. ;) No worries, the answer is found.
Kave