Click here to Skip to main content
15,887,816 members
Please Sign up or sign in to vote.
3.00/5 (1 vote)
I am writing a sort/filter control for an application. What I would like is to use a list view to display the filter and to be able to add and remove lines from the filter. I'm still fairly new to WPF so I can believe I've made some obvious mistakes or missed something else that is simple.

my listview as I currently have it in XAML

<ListView HorizontalAlignment="Stretch" Margin="5" Name="lvFilter" VerticalAlignment="Stretch">
    <ListView.View>
        <GridView>
            <GridViewColumn Header="Column" Width="220">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <ListBox Name="lbColumnList" ItemsSource="{Binding Path=Name, Source={StaticResource AvailableColumns}}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Operation" Width="130">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <ListBox Name="lbOperation" ItemsSource="{Binding Path=Value, Source={StaticResource AvailableOperations}}"/>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Value" Width="250">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBox Name="txtValue"></TextBox>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>


I'm looking to have 2 dropdowns and a textbox. Each of the listboxes will be bound to a valid list. When looking at a saved filter each 'AND' will have a line with the column the operation and the value ie. COST > 1000.

I'm missing some critical information on how to use the ListView at this level and I haven't found any examples even close. No one has an example of how to use a bound listbox in the template.

Any help or examples would be much appreciated.
Posted

1 solution

I think your approach is slightly off if I am understanding what you are trying to build.

In essence you want to build a filter builder correct?
So you want to populate a list with the filters

so something like this

Column A | "operator" | value | And/Or
Column B | "operator" | value | And/Or
Column B | "operator" | value |

If that is the case, I would use an item template that is more like this:

ComboBoxA | ComboBoxB | Textbox | ComboboxC

ComboBoxA's datasource is a list of available columns
ComboBoxB's datasource is a list of available operators (which in turn can be filtered based on the datatype of the selected column
ComboBoxC is empty/and/or (empty for when it is the last option) then as soon as And or Or is selected a new entry in the main list can be added.

Does that make sense?

----------------------------------------------------------------

Okay, so this is what I produced, it is a non-working example but it should point you in the right direction.

This is a DataTemplate to be added to your windows resources:

XML
<DataTemplate x:Key="filterEntry" DataType="MyClasses:FilterComponent">
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <ComboBox Grid.Column="0" Margin="2" ItemsSource="{Binding Path=ColumnList}" SelectedItem="{Binding Path=Column}" />
                <ComboBox Grid.Column="1" Margin="2" ItemsSource="{Binding Path=OperatorList}" SelectedItem="{Binding Path=Operator}" />
                <TextBox Grid.Column="2" Margin="2" Text="{Binding Path=FilterValue}" />
                <ComboBox Grid.Column="3" Margin="2" ItemsSource="{Binding Path=CombinerOperator.Combiner}" SelectedItem="{Binding Path=Combiner}" />
            </Grid>
        </DataTemplate>

HTML


The purpose of this is you designed a class called "FilterComponent" which has properties:
Column, Operator, FilterValue and Combiner, which together make up a section of the filter.
You then use a template selector / a style on the list which applies this data template when a row is selected (no point having all the controls displayed if it is view mode not edit).

On your view model, you have a property that is an observable collection of "FilterComponents" which make up your filter. This observable collection acts as the items source for the listview/listbox.

You also need properties/enums etc to apply as the items sources on the datatemplate.

Hopefully that should help point you in the right direction. :-)
 
Share this answer
 
v2
Comments
bowlturner 6-Aug-13 10:55am    
Yes that is the idea. However, we currently are not planning to let the users have an 'or'. Our database can be brought to it's knees with a poorly used 'or'.

Otherwise yes that is what I want to build. The problem is I don't have any examples of how to have the listview with listboxes inside each row all bound correctly.
Pheonyx 6-Aug-13 11:10am    
Question for you, are you building this using a MVVM approach (it looks like you might be based on your code)
bowlturner 6-Aug-13 11:14am    
Mostly, but I suspect I'm breaking some of the 'rules'. I understand the basic concepts but haven't had any formal training on MVVM.
Pheonyx 6-Aug-13 11:05am    
Okay, I can't knock up an example right now, but I'll see what I can do tonight and post it for you.
It shouldn't be too complicated to produce the basic core of what you are after.
bowlturner 6-Aug-13 11:12am    
That would be awesome. I wasn't paying attention, the ComboBox would be just fine to use as well. May even be more appropriate. Thanks in advance for the help!

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900