2

I'm totally new at WPF and I'm stuck with the bellow situation:

 class Person{
    string Name;
    List<Address> ListAddresses;
 }

I have a DataGrid with ItemsSource as an ObservableCollection<Person>. This collection is in MainViewModel class.

I want to create a DataGridComboBoxColumn with the addresses.

<DataGrid ItemsSource="{Binding Persons, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">
   <DataGrid.Columns>   
      <DataGridComboBoxColumn ItemsSource="{Binding Path=ListAddresses, RelativeSource={RelativeSource Mode=FindAncestor,
         AncestorType={x:Type local:Person}}}">
      </DataGridComboBoxColumn>      
   </DataGrid.Columns>
</DataGrid>

I receive the following error:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='PersonApp.UL.ViewModels.Person', AncestorLevel='1''. BindingExpression:Path=ListAddresses; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=11440639); target property is 'ItemsSource' (type 'IEnumerable')

2
  • You mention MainViewModel, so you're using the MVVM structure? Commented Oct 17, 2017 at 7:30
  • Yes. I am using MVVM. Commented Oct 17, 2017 at 7:33

1 Answer 1

0

DataGridComboBoxColumn is going to cause you many problems. Try this:

    <DataGridTemplateColumn Header="Something"
                            SortMemberPath="[SelectedAddress].[property from Address class]">
        <DataGridTemplateColumn.CellTemplate>
            <DataTemplate>
                <ComboBox ItemsSource="{Binding ListAddresses}"
                          SelectedItem="{Binding SelectedAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                          SelectedValuePath="[SelectedAddress].[property from Address class]"
                          DisplayMemberPath="[property from Address class (like Name)]" />
            </DataTemplate>
        </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>

You should also include SelectedAddress property in your Person class, to store which Address is selected in the ComboBox.

Binding to property that is inside your ItemsSource scope (which in this case is what you bind to DataGrid) does not require RelativeSource binding, that's why you are getting an error. RelativeSource is required in case you set your DataGrid.ItemsSource to for example PeopleList and you want to bind your (that is inside this DataGrid) ComboBox.ItemsSource to a property that is in your ViewModel, but NOT inside your PeopleList.

Another thing for binding to ComboBox is if you bind ItemsSource to a collection of objects other than strings, you have to set DisplayMemberPath to a property in your object, in order to make the control display the right caption. So for example if you are binding object Car and it has a string type property called Name, you should set DisplayMemberPath to Name in order to make your control display list of Car.Names (selecting one will still result in selecting the whole object, not just the Name property).

Sign up to request clarification or add additional context in comments.

3 Comments

You saved my day! Thank you a lot for the detailed and quickly answer!
I'm glad I could help :)
Also if you need binding to ancestor, you should rather try finding an ancestor by control type, not by object from ViewModel type. For example if you have a View which is an UserControl and it has a DataGrid inside it, then you should look for ancestor of type {x:Type UserControl}. This will give you the DataContext of your UserControl, which (if you implement MVVM correctly) is your ViewModel bound to your UserControl.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.