Click here to Skip to main content
13,146,742 members (79,717 online)
Click here to Skip to main content
Add your own
alternative version

Stats

6.4K views
276 downloads
4 bookmarked
Posted 5 Oct 2016

WPF Drop Down Menu Button

, 5 Oct 2016
Rate this:
Please Sign up or sign in to vote.
Presents and implementation of a control that can be pressed to bring up a Menu.

Introduction

There was a need to have a Button for adding elements to an ItemsControl, but there were several different types that could be added. Adding a Button for each would have created a lot of controls, and the other option of adding a ComboBox to specify the type to be added seemed even worse (this was the previous solution). Thus a Button that brought up a number of selections seemed to be obvious. Then the question was what to use, and a Menu control seemed to be the best solution

Implementation

The DropDownButton inherits from the ToggleButton:

public class DropDownButton : ToggleButton
{
   public DropDownButton()
    {
        // Bind the ToogleButton.IsChecked property to the drop-down's IsOpen property
        Binding binding = new Binding("Menu.IsOpen");
        binding.Source = this;
        this.SetBinding(IsCheckedProperty, binding);
        DataContextChanged += (sender, args) =>
        {
            if (Menu != null)
                Menu.DataContext = DataContext;
        };
    }

    // *** Properties ***
    public ContextMenu Menu
    {
        get { return (ContextMenu)GetValue(MenuProperty); }
        set { SetValue(MenuProperty, value); }
    }
    public static readonly DependencyProperty MenuProperty = DependencyProperty.Register("Menu",
        typeof(ContextMenu), typeof(DropDownButton), new UIPropertyMetadata(null, OnMenuChanged));

    private static void OnMenuChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var dropDownButton = (DropDownButton)d;
        var contextMenu = (ContextMenu)e.NewValue;
        contextMenu.DataContext = dropDownButton.DataContext;
    }

    protected override void OnClick()
    {
        if (Menu != null)
        {
            Menu.PlacementTarget = this;
            Menu.Placement = PlacementMode.Bottom;
            Menu.IsOpen = true;
        }
    }

It adds one DependencyProperty for the Menu, which is type ContextMenu,

The first thing that needs to be done is to make the ContextMenu visible when the ToggleButton is in the IsChecked state. The override on the OnClick method does this, and also sets the Placement.

The other necessary thing is to set the DataContext of the ContextMenu. Unfortunately, the DataContext of the ToggleButton is not set to be the DataContext of any of this type of embedded control. Therefore, whenever the Menu DependencyProperty or DataContext for the ToggleButton is changed, the DataContext of the ToggleButton is applied to the DataContext of the Menu. One is done with the change of the Menu DependencyProperty, the other is done by handling the DataContextChanged of the ToggleButton.

Using the Control

The use of the Control is pretty straight forward. It us just like a ToggleButton, but there is an additional DependencyProperty that needs to be set to the instance of a ContextMenu as shown below.

<local:DropDownButton Margin="0,4"
                      HorizontalAlignment="Center"
                      VerticalAlignment="Center"
                      Style="{StaticResource EllipseToggleButtonStyle}">
    <ContentControl ContentTemplate="{StaticResource PlusIcon}" />
    <local:DropDownButton.Menu>
        <ContextMenu>
            <MenuItem Command="{Binding AddCommand}"
                      CommandParameter="{Binding}"
                      Header="Add" />
            <MenuItem Command="{Binding DeleteCommand}"
                      CommandParameter="{Binding}"
                      Header="Delete" />
            <MenuItem Command="{Binding MoveCommand}"
                      CommandParameter="{Binding}"
                      Header="Move" />
        </ContextMenu>
    </local:DropDownButton.Menu>
</local:DropDownButton>

   

History

  • 2016/10/05: Initial version

License

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

Share

About the Author

Clifford Nelson
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

You may also be interested in...

Comments and Discussions

 
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170915.1 | Last Updated 5 Oct 2016
Article Copyright 2016 by Clifford Nelson
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid