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()
{
Binding binding = new Binding("Menu.IsOpen");
binding.Source = this;
this.SetBinding(IsCheckedProperty, binding);
DataContextChanged += (sender, args) =>
{
if (Menu != null)
Menu.DataContext = DataContext;
};
}
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