Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Binding to ViewModel.SubClass.Property (sub-property)

Tags:

mvvm

binding

wpf

let's say i have a section on my screen where "current record" is edited.. so my view model has a class with all currently edited properties such as:

class Record { 
    public string Notes { get { return "Foo"; } set { _notes = value; Notify("Notes"); }
}

and we add this class to the view model:

class AdjustsmentViewModel {
    public Record CurrentRecord { get { return new Record(); }}
}

How can i bind to Notes property of CurrentRecord in my view? I tried this:

<TextBox Text="{Binding CurrentRecord.Notes, Mode=TwoWay}" VerticalScrollBarVisibility="Auto" TextWrapping="WrapWithOverflow" AcceptsReturn="True"  />

This is not working however. I also tried setting DataContext of surrounding StackPanel:

<StackPanel DataContext="{Binding CurrentRecord}">

After that, i tried in my TextBox {Binding Notes} and {Binding Path=Notes}, but none of these seem to work.

Perhaps above really should work and i am messing something elsewhere?

Update

This is happening in a user control. This user control has a separate view model, from it's parent window.

this.DataContext = UnityUtil.Resolve<AdjustmentsViewModel>();

Also i am seeing a binding error: 'Notes' property not found on 'object' ''MainViewModel'

that view model is set on the main window.

to verify that i have the right ViewModel bound, i just added this property directly on the viewmodel:

public string Notes2 { get { return "Bar"; } } 

and corresponding textblock in the view:

<TextBlock Text="{Binding Path=Notes2}" />

this works as expected.

Great Success

Thanks to Ryan, i was able to find the problem. It was not in the property itself, but the way CurrentRecord was being set. In my setter, i make a call to INotifyPropertyChange handler, but that had the old name of the property in it. So the view was not getting a CurrentRecord notification, so i guess Notes notification was not enough ..

in conclusion, this notation is correct: {Binding Path=CurrentRecord.Notes}

like image 919
Sonic Soul Avatar asked Jul 23 '12 20:07

Sonic Soul


2 Answers

The above should work, {Binding Path=CurrentRecord.Notes} is right. Can you check that your datacontext is set to your viewmodel?

Also check if your viewmodel implements INotifyPropertyChanged.

edit: I just created a sample project to recreate this. No need to implement INotifyPropertyChanged, it just works when the datacontext is set to the VM.

like image 161
cguedel Avatar answered Oct 05 '22 22:10

cguedel


Make sure that your CurrentRecord property is 1) being set and 2) notifying the UI layer that a change has occurred.

like image 34
Thelonias Avatar answered Oct 06 '22 00:10

Thelonias