12

Per this page, the DropDownButton is using a ContextMenu to display the ItemsSource. How are we to know what the user clicks on? The Click event on the button isn't for the menu, but the button itself. I see no other events on it.

Joel Lucsy
  • 8,520
  • 1
  • 29
  • 35
  • Check this events: `DropDownOpened/DropDownClosed`, `ContextMenuOpening/ContextMenuClosing`. – Anatoliy Nikolaev Apr 11 '14 at 17:50
  • Don't use events in WPF. Chances are that control has a `SelectedItem` property, -or- that you can assign `Command`s to each item like you would do in a regular `Menu`. – Federico Berasategui Apr 11 '14 at 17:51
  • @HighCore: The DropDownButton is, quote: `This control almost the same as SplitButton with few differences: It has no SelectedItem and SelectedIndex properties and also has no SelectionChanged event.`. – Anatoliy Nikolaev Apr 11 '14 at 17:52
  • 5
    @AnatoliyNikolaev which means it's not a `Selector`. I wonder why would anyone develop a UI element that's supposed to let you select stuff and not inherit from `Selector`.... S: – Federico Berasategui Apr 11 '14 at 17:57

4 Answers4

15

I came across this question looking for the same answer. I never really found anything online but discovered this solution on my own. Perhaps it will help someone in the future.

As stated previously the DropDownButton uses a ContextMenu to display its ItemsSource. Basically what I was looking for was a "Menu-like" drop down coming from a button. For example, say you have a DropDownButton that says "Add". Maybe you want 2 options like "Add New" and "Add Existing". So this is what I did...

First I made some object to hold the header/content and the command.

public class TitledCommand
{
    public String Title { get; set; }
    public ICommand Command { get; set; }
}

Theoretically you would have a list of these to bind to the ItemsSource of the DropDownButton.

public List<TitledCommand> TitledCommmands { get; private set; }

Now we just style the item container for the DropDownButton so it picks up the header and command from our objects in the ItemsSource.

Include MahApps:

xmlns:metroControls="http://metro.mahapps.com/winfx/xaml/controls"

And here is the style...

<metroControls:DropDownButton Content="Add" ItemsSource="{Binding Path=TitledCommmands}">
    <metroControls:DropDownButton.ItemContainerStyle>        
        <Style TargetType="MenuItem">
            <Setter Property="Header" Value="{Binding Path=Title}"/>
            <Setter Property="Command" Value="{Binding Path=Command}"/>
        </Style>          
    </metroControls:DropDownButton.ItemContainerStyle>
</metroControls:DropDownButton>
akagixxer
  • 1,767
  • 3
  • 21
  • 35
3

You can override the item template for the control and can add a handler inside of it like this:

<controls:DropDownButton Content="Select me" x:Name="selectMeDropDownButton">
    <controls:DropDownButton.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" MouseDown="selectMeDropDownButton_TextBlock_MouseDown" />
        </DataTemplate>
    </controls:DropDownButton.ItemTemplate>
</controls:DropDownButton>

And implement the event handler in code-behind file like this:

void selectMeDropDownButton_TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
{
    if (e.ChangedButton == MouseButton.Left && this.selectMeDropDownButton.IsExpanded)
    {
        var value = ((TextBlock)e.Source).DataContext;
        // Do something meaningful with the value, it's an item from ItemsSource
    }
}

The check for DropDownButton.IsExpanded is necessary as the same ItemTemplate is applied to the Content on the button itself. Of course you can replace TextBlock with any Control/UIElement you like.

Aleksej
  • 251
  • 2
  • 6
  • IMO it's better to use `` instead of `` in the ``. – xmedeko Mar 15 '16 at 10:02
  • I've firstly tried your solution, but the event raises only when you click on the TextBlock itself, not on the full dropdown item row. So if the user is not aware of that (and he shouldn't), he won't understand why his click has no effect some times. Finally I had to implement command solution. – Alex Mar 01 '21 at 12:26
0

Create an attached property to the ContextMenu/DropDownButton (whichever you prefer). If you did dropdown then get the context menu that it is showing then hook up the Click events from it and push the value back to the property.

123 456 789 0
  • 10,565
  • 4
  • 43
  • 72
0

Use SplitButton instead of DropDownButton. The first has SelectionChanged event.

Rick
  • 528
  • 1
  • 6
  • 15