WPF: MenuButton

i was looking for a Menu-Button (some call it Drop-Down-Button) and found this post: DropDownButtons in WPF.
all credits goes to Andy, i’ve just adapted his code and idea.
here is my version:

public class MenuButton : ToggleButton
{
    public enum Placement { Bottom, Right }
    public Placement MenuPlacement { private get; set; }

    #region DropDown (DependencyProperty)

    public ContextMenu Menu
    {
        get { return (ContextMenu)GetValue(MenuProperty); }
        set { SetValue(MenuProperty, value); }
    }
    public static readonly DependencyProperty MenuProperty =
        DependencyProperty.Register("Menu", typeof(ContextMenu), typeof(MenuButton),
            new PropertyMetadata(null, OnMenuChanged)
            );

    private static void OnMenuChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ((MenuButton)sender).OnMenuChanged(e);
    }

    private void OnMenuChanged(DependencyPropertyChangedEventArgs e)
    {
        if (Menu != null)
        {
            Menu.PlacementTarget = this;

            switch (MenuPlacement)
            {
                default:
                case Placement.Bottom:
                    Menu.Placement = PlacementMode.Bottom;
                    break;
                case Placement.Right:
                    Menu.Placement = PlacementMode.Right;
                    break;
            }

            this.Checked += new RoutedEventHandler((a, b) => { Menu.IsOpen = true; });
            this.Unchecked += new RoutedEventHandler((a, b) => { Menu.IsOpen = false; });
            Menu.Closed += new RoutedEventHandler((a, b) => { this.IsChecked = false; });
        }
    }

    #endregion

    #region MenuSource (DependencyProperty)

    public IEnumerable MenuSource
    {
        get { return (IEnumerable)GetValue(MenuSourceProperty); }
        set { SetValue(MenuSourceProperty, value); }
    }
    public static readonly DependencyProperty MenuSourceProperty =
        DependencyProperty.Register("MenuSource", typeof(IEnumerable), typeof(MenuButton),
            new PropertyMetadata(null, OnMenuSourceChanged)
            );

    private static void OnMenuSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        ((MenuButton)sender).OnMenuSourceChanged(e);
    }

    private void OnMenuSourceChanged(DependencyPropertyChangedEventArgs e)
    {
        if (Menu == null)
            Menu = new ContextMenu();

        Menu.ItemsSource = e.NewValue as IEnumerable;
    }

    #endregion

}

One Response to WPF: MenuButton

  1. Pingback: Binding ElementName from context menu can't find target

Leave a comment