none
ComboBox in a Listview, with dynamic bindings RRS feed

  • Question

  • Hi Guys,
    I need to embed a ComboBox with a ListView (GridView).

    Basically I need to display a ListView/GridView, which has three columns: Name, Operator, Value. I need to bind the ListView to a collection of objects I get from DB. Each row is a class object, which can be simplified as:

    public class Attribute
    {
    public string Name{get;set;}
    public string Operator{get;set;}
    public string Value{get;set;}
    }

    A sample of a collection of Attribute objects can be:

    ("ServiceType", ...) ("Content", ...) ("Status", ...)

    The first column is just a simple TextBlock showing the name (ServiceType, Content, Status or etc.). Based on the Name column for each row, I need to populate the "Value" column for that row with a ComboBox, but showing specific items that are suitable for the Name. 

    For example, if the Name for a row is "ServiceType", I need to populate the Combobox for that row with the following items:
    "sour", "sweet" and "unsure". 

    If the name for the second row is "Status", I need to poputlate the ComboBox for the second row with the following items:
    "new", "reconditioned", "unsure", and "used".

    The idea is the user can select one of the pre-defined value from the ComboBox. Such as "sweet" for the ServiceType, and "reconditioned" for the Status. And I can build a SQL query based on what the user selects.

    How do I do this in WPF?

    Currently I have the "inner" ComboBox binds to a CollectionViewSource defined in the <Window.Resources>, and at the ListView.SelectionChange event, I dynamically update CollectionViewSource's Source property. 

    This works and the ComboBox shows the correct items. But when I switch from one list item to the other, say, from ServiceType to Status, the previously selected item is lost, this is because I guess I only have one CollectionViewSource, and I have multiple ComboBox binding to it.

    How do I dynamically create multiple CollectionViewSource and have the ComboBox bind to different ones?


    Thanks!
    Wenbiao
    Tuesday, February 3, 2009 10:07 PM

Answers

  • You might only show the ComboBox in the selected ListViewItem. When a listview item is not selected, display the current value in a textblock. You can use a DataTrigger to switch the datatemplate

    <GridViewColumn Header="Batch"   
                    Width="100"   
                    > 
        <GridViewColumn.CellTemplate> 
            <DataTemplate> 
                <ContentControl x:Name="tbDisplay">  
                    <ContentControl.Template> 
                        <ControlTemplate> 
                            <TextBlock Style="{StaticResource TextBlockStatePointStyle}" 
                                       Text="{Binding Path=AssemblyDM.BatchID, Mode=OneWay}" 
                                       /> 
                        </ControlTemplate> 
                    </ContentControl.Template> 
                </ContentControl> 
                <DataTemplate.Triggers> 
                    <DataTrigger Binding="{Binding Path=IsSelected}" Value="True">  
                        <Setter TargetName="tbDisplay" Property="Template">  
                            <Setter.Value> 
                                <ControlTemplate> 
                                    <ComboBox Style="{StaticResource ComboBoxInListViewStatePointStyle}"   
                                              IsEditable="False" 
                                              HorizontalAlignment="Stretch" 
                                              ItemsSource="{Binding Source={StaticResource odpBatchs}}" 
                                              ItemTemplate="{StaticResource ComboBoxBatchItemTemplate}" 
                                              SelectedValuePath="BatchID" 
                                              SelectedValue="{Binding Path=AssemblyDM.BatchID, Mode=TwoWay}" 
                                              > 
                                    </ComboBox> 
                                </ControlTemplate> 
                            </Setter.Value> 
                        </Setter> 
                    </DataTrigger> 
                </DataTemplate.Triggers> 
            </DataTemplate> 
        </GridViewColumn.CellTemplate> 
    </GridViewColumn> 
     

    Note that my DataTrigger triggers on an IsSelected property in the bound LVI DataContext. You'd need to use a RelativeSource to bind to the LVI ISSelected property.

    • Marked as answer by Hua Chen Tuesday, February 10, 2009 9:58 AM
    Wednesday, February 4, 2009 1:20 AM