0
votes

I am trying to bind a ListBox from the View to a class in the ViewModel. I have no trouble binding it inside the main View. But when I try to do some binding in the other XAML views, I am getting the below error. What is the problem here?

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='OutlookCalendar.Controls.OpenSummaryLine', AncestorLevel='1''. BindingExpression:Path=SummaryLines; DataItem=null; target element is 'ListBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')

<ListBox Grid.Row="6"
         Grid.ColumnSpan="3" 
         Background="White" 
         Margin="5,0,22,5" 
         ItemsSource="{Binding SummaryLines, 
                               RelativeSource={RelativeSource AncestorType={x:Type local:OpenSummaryLine}}}" 
         IsSynchronizedWithCurrentItem="True" />
2
It sounds like you have the view in a UserControl and there isn't that RelativeSource in there. Can you bind the UserControl's DataContext in each view and not use RealativeSource?kenny
If your main window view is OpenSummaryLine and SummaryLines is the property of the main window's view model then try Path=DataContext.SummaryLinesUttam K C
@kenny Hi thanks for your suggestion. I am very new to WPF, how could I exactly achieve this?user3854148
@UttamKC Thanks for your reply, OpenSummaryLine is not my main window's view, it is only one of the views. How can I achieve data binding in these other views?user3854148
@user3854148 something like <views:MyUserControl DataContext="{Binding what-your-control-binds-to}" />kenny

2 Answers

1
votes

When you use RelativeSource or ElementName in a Binding, you are binding to the object and not to the object's data context. For that you'll need to prefix your binding path with 'DataContext'. Try this:

ItemsSource="{Binding DataContext.SummaryLines, 
                               RelativeSource={RelativeSource AncestorType={x:Type local:OpenSummaryLine}}}"
1
votes

You cannot use a RelativeSource Binding if the source is not relative to (or more accurately, a parent of) the control with the relevant Binding. From the Binding.RelativeSource Property page on MSDN:

Gets or sets the binding source by specifying its location relative to the position of the binding target.

Therefore, if your required source has no relation to the control with the relevant Binding, you will get the error that you did, which basically means:

Cannot find an OpenSummaryLine element that is relative to the ListBox Binding.

One simple solution is to move the source collection to a common parent, with the object that you have set as the MainWindow.DataContext property being the most likely target. If you add a SummaryLines property into that object, then you can use a RelativeSource Binding to access it from every control displayed in the MainWindow, either directly, or indirectly in UserControls:

<ListBox Grid.Row="6" Grid.ColumnSpan="3" Background="White" Margin="5,0,22,5" 
    ItemsSource="{Binding DataContext.SummaryLines, RelativeSource={RelativeSource 
    AncestorType={x:Type local:MainWindow}}}" 
    IsSynchronizedWithCurrentItem="True" />

Of course, the local XAML Namespace Prefix used here would have to reference the assembly that MainWindow is declared in for this to work. You could use the same Binding.Path in your OpenSummaryLine view too and it will data bind to the same collection.