Hardgraf
Hardgraf

Reputation: 2626

WPF DataGridComboBoxColumn Binding?

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

Upvotes: 1

Views: 9837

Answers (3)

AnjumSKhan
AnjumSKhan

Reputation: 9827

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);
        }

Upvotes: -1

waqar ahmed
waqar ahmed

Reputation: 335

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; }
    }

Upvotes: 1

Sheridan
Sheridan

Reputation: 69959

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.

Upvotes: 1

Related Questions