1

I'm trying to include a ComboBox column in a WPF datagrid. I'm trying to bind this column to an observable collection in the ViewModel however, at run time the cells remain empty. Datacontext is correct, as all normal columns bind successfully. I want to display 'regionShortCode' in the UI. Here's my xaml:

   <DataGridComboBoxColumn Header="Region" DisplayMemberPath="regionShortCode" Width="SizeToHeader">
       <DataGridComboBoxColumn.ElementStyle>
           <Style>
             <Setter Property="ComboBox.ItemsSource" Value="{Binding Path=MembershipsCollection}" />
             </Style>
                </DataGridComboBoxColumn.ElementStyle>
                 <DataGridComboBoxColumn.EditingElementStyle>
              <Style>
                 <Setter Property="ComboBox.ItemsSource" Value="{Binding Path=MembershipsCollection}" />
              </Style>
           </DataGridComboBoxColumn.EditingElementStyle>
     </DataGridComboBoxColumn>

& here is my ObservableCollection declared in the ViewModel. The Collection is populated successfully from a method invoked in the constructor:

private ObservableCollection<tbAccountMembership> _MembershipsCollection;
    public ObservableCollection<tbAccountMembership> MembershipsCollection
    {
        get { return _MembershipsCollection; }
        set
        {
            _MembershipsCollection = value;
            OnPropertyChanged("MembershipsCollection");
        }
    }     

At run time I get:

System.Windows.Data Error: 40 : BindingExpression path error: 'MembershipsCollection' property not found on 'object' ''tbAccountMembership_041E43AFC29975F12C156BA1373ACD47FC07BBE55614E5AF8AD3BBD9F090C133' (HashCode=46247020)'. BindingExpression:Path=MembershipsCollection; DataItem='tbAccountMembership_041E43AFC29975F12C156BA1373ACD47FC07BBE55614E5AF8AD3BBD9F090C133' (HashCode=46247020); target element is 'TextBlockComboBox' (Name=''); target property is 'ItemsSource' (type 'IEnumerable')

in the Output window. Why can't the Xaml resolve this binding? Thanks

4
  • I'm trying to bind this column to an observable collection in the ViewModel... is this right? You want to data bind to a single collection property in the view model and not one in the data item class? If so, then your answer to Why can't the Xaml resolve this binding? is because you didn't tell the Framework where to look for the actual property... you'll need to use a RelativeSource Binding. Commented Sep 3, 2014 at 12:15
  • I want to bind to a single element within the ObservableCollection Commented Sep 3, 2014 at 12:17
  • Where is the ObservableCollection<T> declared? Commented Sep 3, 2014 at 12:18
  • In the ViewModel as a public property. Question updated. Commented Sep 3, 2014 at 12:21

3 Answers 3

1

If you want to data bind to a single collection property in the view model from the DataGrid, then your answer to Why can't the Xaml resolve this binding? is because you didn't tell the Framework where to look for the actual property... you'll need to use a [RelativeSource Binding]1. Try this instead:

<DataGridComboBoxColumn Header="Region" DisplayMemberPath="regionShortCode" 
    Width="SizeToHeader">
    <DataGridComboBoxColumn.ElementStyle>
        <Style>
            <Setter Property="ComboBox.ItemsSource" Value="{Binding 
                DataContext.MembershipsCollection, RelativeSource={RelativeSource 
                AncestorType={x:Type YourViewModelsPrefix:YourViewModel}}}" />
        </Style>
    </DataGridComboBoxColumn.ElementStyle>
    <DataGridComboBoxColumn.EditingElementStyle>
        <Style>
            <Setter Property="ComboBox.ItemsSource" Value="{Binding 
                DataContext.MembershipsCollection, RelativeSource={RelativeSource 
                AncestorType={x:Type YourViewsPrefix:YourView}}}" />
        </Style>
    </DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>

With this Binding Path, the Framework will look outside of the normal DataGrid.DataContext for a property named MembershipsCollection in the object that is set as the DataContext of the YourView (clearly this is not the actual name) UserControl or Window. If y our view model is correctly set as the DataContext then this should work just fine.

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

Comments

1

You have to provide exact path to the collection to bind with the itemssource of the combobox. for this make your ancestor as your main control i.e window or the usercontrol

           <DataGridComboBoxColumn Header="Category"
SelectedValueBinding="{Binding category_cde}"
  SelectedValuePath="category_cde"
DisplayMemberPath="category_dsc">
                        <DataGridComboBoxColumn.ElementStyle>
                            <Style TargetType="ComboBox">
                            <Setter Property="ItemsSource" Value="{Binding Path=CATEGORIES , RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                            </Style>
                        </DataGridComboBoxColumn.ElementStyle>
                        <DataGridComboBoxColumn.EditingElementStyle>
                            <Style TargetType="ComboBox">
                            <Setter Property="ItemsSource" Value="{Binding Path=CATEGORIES , RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                            </Style>
                        </DataGridComboBoxColumn.EditingElementStyle>
                    </DataGridComboBoxColumn>

            </DataGrid.Columns>
        </DataGrid>

And here is the collection of categories i defined in code behind where category is some class you can define your own collection

 List<Category> m_categories = new List<Category>();
    public List<Category> CATEGORIES
    {
        get { return m_categories; }
        set { m_categories = value; }
    }

Comments

-1

A much easier solution with DataGridComboBoxColumn is to set ItemSource binding programmatically in Window class' constructor.

<DataGrid x:Name="MembershipGridNormal" AutoGenerateColumns="False" SelectedIndex="0" ItemsSource="{Binding}">
            <DataGrid.Columns>

                <DataGridTextColumn Header="Name" Binding="{Binding Prop1}"/>
                <DataGridTextColumn Header="Value" Binding="{Binding Prop2}"/>
                <DataGridComboBoxColumn x:Name="CmbMemberShips" Header="RawValues" DisplayMemberPath="Name" />

            </DataGrid.Columns>
        </DataGrid>

in code behind

public Win32599087()
        {
            InitializeComponent();

            MemberShipGridNormal.DataContext = myCollection;

            Binding b = new Binding();
            b.Source =  myCollection;
            b.Path = new PropertyPath("collectionpropertyname");

            BindingOperations.SetBinding(CmbMemberships, DataGridComboBoxColumn.ItemsSourceProperty, b);
        }

Comments

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.