DocDawg
DocDawg

Reputation: 1

WPF DataGridTemplateColumn with ComboBox binding at runtime (not MVVM)

I've poured over the answers and examples here but none seem to address my case.

I have a typical DataGridTemplateColumn with a TextBlock and ComboBox:

<DataGridTemplateColumn Header="Section" SortMemberPath="SectionName" CanUserSort="True">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding SectionName}">
                <TextBlock.Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="Background" Value="{Binding SectionName, Converter={StaticResource SectionBackgroundConverter}}"/>
                        <Setter Property="Padding" Value="5,5,5,5"></Setter>
                    </Style>
                </TextBlock.Style>
            </TextBlock>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
    <DataGridTemplateColumn.CellEditingTemplate >
        <DataTemplate >
            <ComboBox x:Name="cmbSections" ItemsSource="{Binding Path=g_colZDSectionNames}" SelectedItem="{Binding SectionName}" FocusManager.FocusedElement="{Binding RelativeSource={RelativeSource Self}}" />
        </DataTemplate>
    </DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>

The TextBlock is bound to an object in a list of objects that is bound to the DataGrid. It shows its property as expected.

The ComboBox needs to bind to a collection of strings that is unknown at runtime until a function calls a web service to fetch the values. Then I bind another ComboBox named cmbDefaultSections that is not in the DataGrid to the following ZDSection object. It shows the list as expected. But the ComboBox named cmbSections in the DataGrid remains empty if I bind it to the same object or if I bind it to an ObservableCollection(Of String) as suggested. I suspect it is because the DynamicResource named Sections is Nothing when the ComboBox is created at run-time, as expected.

In my code-behind, I'm setting the ItemsSource of the other ComboBox like this:

    cmbDefaultSections.ItemsSource = New ZDSections.ZDSection

Now how can I set cmbSections similarly? It's inaccessible from code. I've tried implementing INotifyCollectionChanged on the collection object so that it will auto-update, but to no avail:

Public Class ZDSection
    Inherits ObservableCollection(Of String)
    Implements INotifyCollectionChanged

    Public Sub New()
        If g_lstZDSections IsNot Nothing Then
            For Each section In g_lstZDSections
                Me.Add(section.Name)
            Next section
            Call OnCollectionChanged(New NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset))
        End If
    End Sub

    Public Shadows CollectionChanged As NotifyCollectionChangedEventHandler

    Protected Overrides Sub OnCollectionChanged(e As NotifyCollectionChangedEventArgs)
        MyBase.OnCollectionChanged(e)
        If CollectionChanged IsNot Nothing Then
            CollectionChanged.Invoke(Me, e)
        End If
    End Sub

End Class

Thanks in advance for your advice!

Upvotes: 0

Views: 1131

Answers (2)

DocDawg
DocDawg

Reputation: 1

After days of dead ends, finally got it to work using a CollectionViewSource as described in Loading Data and Binding Controls in WPF with CollectionViewSource.

Upvotes: 0

dytori
dytori

Reputation: 487

Assign ItemsSource should be done only once. It seems that ZDSection is over kill, just ObservableCollection<string> is enough because it innately notifies collection change and ComboBox item is updated.

comboBox.ItemsSouce = stringCollection;

Elsewhere:

stringCollection.Add(stringFetched);

Upvotes: 0

Related Questions