0
votes

I'm new to WPF. I have a combobox which when choosing a value three other fields (AbbrBlock, MultiBrandSupplier, IgnoreNoCompetition) update along to show the correct relevant values according to the data source. No problem with this.

Issue arises when I try to add to the combobox a custom value, although the combobox shows all values correctly, the other fields don't change when changing the combobox's value.

Here's the working code (without the additional custom combobox value - stripped to the key pieces):

<Window.Resources>
    <local:OrdersDataSet x:Key="ordersDataSet" />
    <CollectionViewSource x:Key="caSuppliersViewSource" Source="{Binding CaSuppliers, Source={StaticResource ordersDataSet}}"/>
</Window.Resources>

...

<StackPanel DataContext="{StaticResource caSuppliersViewSource}">
    <ComboBox Name="SupplierDropdown" DisplayMemberPath="SupplierName" 
        ItemsSource="{Binding Source={StaticResource ResourceKey=caSuppliersViewSource}}"/>
    <TextBlock Name="AbbrBlock" VerticalAlignment="Center" Text="{Binding Abbr}"/>
    <CheckBox Name="MultiBrandSupplier" IsChecked="{Binding MultiBrand}"/>
    <CheckBox Name="IgnoreNoCompetition" IsChecked="{Binding IgnoreNoCompetition}"/>
</StackPanel>

Here's the code with the added custom value which shows correctly but the other fields don't update when changing the combobox value:

<Window.Resources>
    <local:OrdersDataSet x:Key="ordersDataSet" />
    <CollectionViewSource x:Key="caSuppliersViewSource" Source="{Binding CaSuppliers, Source={StaticResource ordersDataSet}}"/>
</Window.Resources>

...

<StackPanel DataContext="{StaticResource caSuppliersViewSource}">
    <StackPanel.Resources>
        <CompositeCollection x:Key="myCompositeCollection">
            <CollectionContainer Collection="{Binding Source={StaticResource ResourceKey=caSuppliersViewSource}}" />
            <ComboBoxItem Content="Add New..." />
        </CompositeCollection>
    </StackPanel.Resources>
    <ComboBox Name="SupplierDropdown" DisplayMemberPath="SupplierName" 
        ItemsSource="{Binding Source={StaticResource myCompositeCollection}}"/>
    <TextBlock Name="AbbrBlock" VerticalAlignment="Center" Text="{Binding Abbr}"/>
    <CheckBox Name="MultiBrandSupplier" IsChecked="{Binding MultiBrand}"/>
    <CheckBox Name="IgnoreNoCompetition" IsChecked="{Binding IgnoreNoCompetition}"/>
</StackPanel>

What am I missing here?

1
Does caSuppliersViewSource have a property named Abbr? I'm struggling to understand that part. - 15ee8f99-57ff-4f92-890c-b56153
@EdPlunkett caSuppliersViewSource was created automatically by Visual Studio when dragging ordersDataSet from the DataSource panel, which in turn is linked to a database in SQL Server. In short, caSuppliersViewSource derives from a table which has a column named abbr. - Sam White
Ok. Can you describe exactly what you see in the UI now (screenshot would be great) and exactly what you want to see (same screenshot crudely edited in MS paint would be perfect)? - 15ee8f99-57ff-4f92-890c-b56153
Are you saying that when you select an existing combo box item, you expect its properties to display in AbbrBlock etc., but they don't? - 15ee8f99-57ff-4f92-890c-b56153
Exactly. The first code above works great but the combobox doesn't show the additional item, and when adding the custom item as shown in the later code block, AbbrBlock and the other two checkboxes don't update to display the correct information. - Sam White

1 Answers

1
votes

Looks like the ComboBox was updating caSuppliersViewSource's View.CurrentItem property (I think) to match its SelectedItem in your first snippet. In the second, the CollectionViewSource is buried inside a CompositeCollection so that doesn't happen any more. However, the ComboBox is still selecting an item, and you can just bind to that using ElementName. No need for setting the DataContext on the StackPanel with this version.

<StackPanel>
    <StackPanel.Resources>
        <CompositeCollection x:Key="myCompositeCollection">
            <CollectionContainer Collection="{Binding Source={StaticResource ResourceKey=caSuppliersViewSource}}" />
            <ComboBoxItem Content="Add New..." />
        </CompositeCollection>
    </StackPanel.Resources>
    <ComboBox 
        Name="SupplierDropdown" 
        DisplayMemberPath="SupplierName" 
        ItemsSource="{Binding Source={StaticResource myCompositeCollection}}"
        />
    <TextBlock 
        Name="AbbrBlock" 
        VerticalAlignment="Center" 
        Text="{Binding SelectedItem.Abbr, ElementName=SupplierDropdown}"
        />
    <CheckBox 
        Name="MultiBrandSupplier" 
        IsChecked="{Binding SelectedItem.MultiBrand, ElementName=SupplierDropdown}"
        />
    <CheckBox 
        Name="IgnoreNoCompetition" 
        IsChecked="{Binding SelectedItem.IgnoreNoCompetition, ElementName=SupplierDropdown}"
        />
</StackPanel>

You could also give eyour viewmodel a SelectedDBItem property of the same type as whatever caSuppliersViewSource contains, and bind ComboBox.SelectedItem to that. Then you could do this:

    <TextBlock 
        Name="AbbrBlock" 
        VerticalAlignment="Center" 
        Text="{Binding SelectedDBItem}"
        />

But that's six dozen of one, half of another, or something -- unless you want to do something else with SelectedDBItem in your viewmodel, then it's handy.