Как узнать, что нажимается на DropDownButton

Per эта страница, DropDownButton использует ContextMenu для отображения ItemsSource. Как узнать, что пользователь нажимает? Событие Click на кнопке не для меню, а сама кнопка. Я не вижу других событий.

Ответ 1

Я столкнулся с этим вопросом, ища тот же ответ. Я никогда ничего не нашел в Интернете, но сам открыл это решение. Возможно, это поможет кому-то в будущем.

Как указано ранее, DropDownButton использует ContextMenu для отображения своего ItemsSource. В основном то, что я искал, было "Показ меню", который выходил из кнопки. Например, скажем, у вас есть DropDownButton, который говорит "Добавить". Возможно, вам нужны два варианта: "Добавить новый" и "Добавить существующий". Так вот что я сделал...

Сначала я сделал некоторый объект для хранения заголовка/содержимого и команды.

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

Теоретически у вас есть список из них для привязки к ItemsSource DropDownButton.

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

Теперь мы просто создаем контейнер item для DropDownButton, чтобы он собирал заголовок и команду из наших объектов в ItemsSource.

Включить MahApps:

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

И вот стиль...

<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>

Ответ 2

Вы можете переопределить шаблон элемента для элемента управления и добавить в него обработчик следующим образом:

<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>

И реализовать обработчик события в файле с кодом ниже:

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 an item from ItemsSource
    }
}

Проверка на DropDownButton.IsExpanded необходима, так как те же ItemTemplate применяются к Content на самой кнопке. Конечно, вы можете заменить TextBlock любым Control/UIElement, который вам нравится.

Ответ 3

Создайте attached property для ContextMenu/DropDownButton (в зависимости от того, что вы предпочитаете). Если вы выпадаете, выберите контекстное меню, которое оно отображает, затем подключите к нему события Click и верните значение обратно в свойство.

Ответ 4

Используйте SplitButton вместо DropDownButton. Первый имеет событие SelectionChanged.