Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WPF

Header Style Combo Box Drop Down Filter Button

5.00/5 (2 votes)
17 Jan 2014CPOL2 min read 18.3K  
Header Style Combo Box Drop Down Filter Button

Introduction

I had run into an issue where I wanted to use a Combo box in the header of a GridView control.

This control would be used for filtering the data in the columns. I wanted specific text (Column Headers) to appear in the combobox and when the client clicked anywhere in the combobox, the drop down would appear and the user can click the item to filter on.

Once the user clicked the desired filter item, the combobox would close and the header would be back.

Background 

There are a few ways of doing this, but the drop down needed to be fully clickable, and I did not want the I style cursor. Nor did I want the text to be highlighted once clicked on the combobox.

How did I resolve this?

I added the combo boxes to the headers template to the gridview and then I styled most of it into place.

Please see the below code.

Using the Code

First, I created the ListView and morphed that to a gridview

XML
<ListView DockPanel.Dock="Top" Name="ListView_DataQuery">
                <ListView.View>
                    <GridView>

                        <GridViewColumn x:Name="ComputerName" 
                                        DisplayMemberBinding="{Binding ComputerName}" 
                                        Header="Computer Name"></GridViewColumn>
                        <GridViewColumn x:Name="Name" 
                                        DisplayMemberBinding="{Binding Name}" 
                                        Header="Property Name"></GridViewColumn>
                        <GridViewColumn x:Name="Type" 
                                        DisplayMemberBinding="{Binding Type}" 
                                        Header="Property Type"></GridViewColumn>
                        <GridViewColumn x:Name="Value" 
                                        DisplayMemberBinding="{Binding Value}" 
                                        Header="Property Value"></GridViewColumn>
                        <GridViewColumn x:Name="Instance" 
                                        DisplayMemberBinding="{Binding RelPath}" 
                                        Header="Instance"></GridViewColumn>

                    </GridView>
                </ListView.View>
            </ListView> 

A Simple List View/Grid View with member displayed bindings

Now some styling to add some epic awesomeness.

XML
<Style TargetType="GridViewColumnHeader" >
            <Setter Property="ContentTemplate">
                <Setter.Value>
                    <DataTemplate>
                        <DockPanel>
                            <Grid>
                                <ComboBox Background="Transparent" 
                                          Foreground="Black" 
                                          BorderBrush="Transparent" 
                                          MaxDropDownHeight="8000"
                                          Name="ComboBox_DataQuery_SelectedItem"
                                          MinWidth="120" 
                                          DockPanel.Dock="Right" 
                                          HorizontalAlignment="Right" 
                                   SelectedItem="{Binding Filter_ListView_DataQuery}" 
                                   SelectedIndex="{Binding FilterIndex_ListView_DataQuery}" 
                                          Drop="ComboBox_GridView_Filter_DropDownClosed"
                                   DropDownOpened="ComboBox_GridView_Filter_DropDownOpen"
                  DropDownClosed="ComboBox_GridView_Filter_DropDownClosed" Uid="{Binding}"
                                          />
                                <Label Margin="0,0,20,0" 
                                       DockPanel.Dock="Left" 
                                       HorizontalContentAlignment="Right" 
                                       Background="Transparent" 
                                       BorderBrush="Transparent"
                                       IsHitTestVisible="False"  
                                       Focusable="False"
                                       Content="{Binding}"/>
                            </Grid>
                        </DockPanel>
                    </DataTemplate>
                </Setter.Value>
            </Setter>
        </Style>

A lot going on here, but basically what this has done is put a Label underneath the combobox.

I have set the background property to transparent so we can see the text, and the text is bound to the column headers of the gridview.

The Selected Item and the Selected index have been bound to public properties, this is for functionality.

There are some Events as well for more functionality, in a perfect world these events would be bound as well.

So now we have dropdown comboboxes that sort of work.

But there is code required:

C#
private void ComboBox_GridView_Filter_DropDownClosed(object sender, EventArgs e)
       {
           //Ensures that once the item has been clicked that the <br />            //item name does not appear in the headered item
           ComboBox ComboBoxDroppedDown = (ComboBox)sender;
           ComboBoxDroppedDown.SelectedIndex = -1;
       }

When you close the combo box, the value that you clicked will be removed, this is so that you don't have overlapping texts..

This is basically all you require for the visual effects.

Points of Interest

In my specific case, I used a DataTable to enter data into my Gridview. This helped in the filtering and whatever. However, having a combobox that you can click, that uses the same cursor and drops down but still acts like a header.

History

Yes, I know this isn't strict to the MVVM model, however it is just an example of how to style the button to how I needed it. I'm sure that you can massage it to how you might require it.

This is my first tip. I hope it helps you because I searched for a fair while and went asking for help and eventually sorted it out.

License

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