Friday, March 21, 2014

Button inside WPF ComboBox

Introduction

A ComboBox control is an items control that works as a ListBox control but only one item from the collection is visible at a time and clicking on the ComboBox makes the collection visible and allows users to pick an item from the collection. Unlike a ListBox control, a ComboBox does not have multiple item selection. A ComboBox control is a combination of three controls - A Button, a Popup, and a TextBox. The Button control is used to show or hide available items and Popup control displays items and let user select one item from the list. The TextBox control then displays the selected item.
This article demonstrates how to create a custom ComboBox control in WPF.

Skeleton of the XAML

<Window x:Class="CustomDropdown.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow"
        SizeToContent="WidthAndHeight"
        ResizeMode="CanMinimize"
        Loaded="Window_Loaded" >

    <Grid Margin="30">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>


        <ToggleButton Name ="button" Grid.Column="0" Grid.Row="2" Height="30" Width="200">
           
            <Grid Width="180" Margin="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="10"/>
                </Grid.ColumnDefinitions>

                <TextBlock  Grid.Column="0" Grid.Row="0" x:Name="txtblock" Text="{Binding ElementName=lstBox,Path=SelectedValue}"/>
               
                <Path Grid.Column="1" Grid.Row="0" HorizontalAlignment="Right" VerticalAlignment="Center" Data="M 0 0 L 4 4 L 8 0 Z" IsEnabled="{Binding ElementName=button,Path=IsEnabled}">
                    <Path.Style>
                        <Style TargetType="{x:Type Path}">
                            <Setter Property="Fill" Value="Black" />
                            <Style.Triggers>
                                <Trigger Property="IsEnabled" Value="False">
                                    <Setter Property="Fill" Value="Gray"/>
                                </Trigger>
                                <Trigger Property="IsEnabled" Value="True">
                                    <Setter Property="Fill" Value="Black"/>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Path.Style>
                </Path>

                <Popup Name="popUp"
                       Width="{Binding ElementName=button,Path=Width}"
                       PlacementTarget="{Binding ElementName=button}"
                       IsOpen="{Binding IsChecked, ElementName=button}"
                       StaysOpen="False"
                       Focusable="True"
                       AllowsTransparency="True"
                       PopupAnimation="Slide"
                       Placement="Top" >
                    <StackPanel>
                        <Button Name="btn"
                        Height="25"
                        IsDefault="True"
                        Click="Button_Click"
                        Focusable="False"
                        IsEnabled="{Binding ElementName=lstBox,Path=HasItems}">Click Me</Button>
                        <ListBox x:Name="lstBox" Focusable="True" TabIndex="1" KeyboardNavigation.TabNavigation="Continue" Height="400"/>
                    </StackPanel>

                </Popup>
            </Grid>
        </ToggleButton>

    </Grid>
</Window>

The structure of controls that are incorporated is shown below

The Path element is used to draw the arrow which looks as we expect. This is done in ToggleButton control template

Expected Output


External Resources


Post a Comment