-
-
Save ryanvs/8059757 to your computer and use it in GitHub Desktop.
<UserControl | |
x:Class="DropDownButtonExample" | |
x:Name="ThisControl" | |
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" | |
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" | |
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" | |
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" | |
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors" | |
xmlns:local="clr-namespace:DropDownButtonExample" | |
mc:Ignorable="d" | |
d:DesignHeight="400" d:DesignWidth="600" | |
> | |
<Grid> | |
<ToolBar Grid.Row="0" ToolBarTray.IsLocked="True" SnapsToDevicePixels="True"> | |
<Button> | |
<behaviors:Interaction.Behaviors> | |
<local:DropDownButtonBehavior/> | |
</behaviors:Interaction.Behaviors> | |
<Button.Content> | |
<StackPanel Orientation="Horizontal"> | |
<Image Source="/DropDownButtonExample;component/Assets/add.png" SnapsToDevicePixels="True" Height="16" Width="16" /> | |
<TextBlock Text="Add"/> | |
<Separator Margin="2,0"> | |
<Separator.LayoutTransform> | |
<TransformGroup> | |
<TransformGroup.Children> | |
<TransformCollection> | |
<RotateTransform Angle="90"/> | |
</TransformCollection> | |
</TransformGroup.Children> | |
</TransformGroup> | |
</Separator.LayoutTransform> | |
</Separator> | |
<Path Margin="2" VerticalAlignment="Center" Width="6" Fill="#FF527DB5" Stretch="Uniform" HorizontalAlignment="Right" Data="F1 M 301.14,-189.041L 311.57,-189.041L 306.355,-182.942L 301.14,-189.041 Z "/> | |
</StackPanel> | |
</Button.Content> | |
<Button.ContextMenu> | |
<ContextMenu> | |
<MenuItem Header="Attribute"/> | |
<MenuItem Header="Setting"/> | |
<Separator/> | |
<MenuItem Header="Property"/> | |
</ContextMenu> | |
</Button.ContextMenu> | |
</Button> | |
</ToolBar> | |
</Grid> | |
</UserControl> |
This is free and unencumbered software released into the public domain. | |
Anyone is free to copy, modify, publish, use, compile, sell, or | |
distribute this software, either in source code form or as a compiled | |
binary, for any purpose, commercial or non-commercial, and by any | |
means. | |
In jurisdictions that recognize copyright laws, the author or authors | |
of this software dedicate any and all copyright interest in the | |
software to the public domain. We make this dedication for the benefit | |
of the public at large and to the detriment of our heirs and | |
successors. We intend this dedication to be an overt act of | |
relinquishment in perpetuity of all present and future rights to this | |
software under copyright law. | |
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | |
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | |
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
OTHER DEALINGS IN THE SOFTWARE. | |
For more information, please refer to <http://unlicense.org/> |
It works like a charm! Thank you:)
Nice - this worked great for me!
To programmatically attach in code:
var ctxm = new ContextMenu();
btnDrop.ContextMenu = ctxm;
var behaviors = Interaction.GetBehaviors(btnDrop);
behaviors.Add(new DropDownButtonBehavior());
Not sure if this is still being monitors or not but if it is I love your example and plan to use the idea in my own work. One thing I have not been able to figure out is how to add context to the menu items. How do i tell it to do what the menu item says when the user clicks on it? Is there a way to bind menu items to code or do i somehow reference the heading in my code?
@funkel1989 I didn't see your comment until now. Normally I would use ICommand
for each of the menu items to bind against the view model. So example code for the menu would be:
<ContextMenu>
<MenuItem Header="Attribute" Command="{Binding AttributeCommand}"/>
<MenuItem Header="Setting" Command="{Binding SettingCommand}"/>
<Separator/>
<MenuItem Header="Property" Command="{Binding PropertyCommand}"/>
</ContextMenu>
Occasionally there are issues with the context menu and visual tree so you can use a BindingProxy (google WPF BindingProxy for more info). In that case, the example code is:
<ContextMenu>
<MenuItem Header="Attribute" Command="{Binding Data.AttributeCommand, Source={StaticResource proxy}}"/>
<MenuItem Header="Setting" Command="{Binding Data.SettingCommand, Source={StaticResource proxy}}"/>
<Separator/>
<MenuItem Header="Property" Command="{Binding Data.PropertyCommand, Source={StaticResource proxy}}"/>
</ContextMenu>
<!-- or -->
<ContextMenu DataContext="{Binding Data, Source={StaticResource proxy}}">
<MenuItem Header="Attribute" Command="{Binding AttributeCommand}"/>
<MenuItem Header="Setting" Command="{Binding SettingCommand}"/>
<Separator/>
<MenuItem Header="Property" Command="{Binding PropertyCommand}"/>
</ContextMenu>
You should attach a licence to this gist to make clear when we are allowed to reuse this code as is.
@RedX2501 Good point. I was debating on MIT but this code is basic that I chose unlicensed instead.
Hello,
I am very new to this stuff. Can you please tell me how and where to attach this menu code to my button? I want this menu to open when I press the button on the Home Window.
Right now, I have a Home Window with a button.
My HomeWindow Code looks like this:
public partial class HomeWindow : Window
{
public HomeWindow()
{
InitializeComponent();
}
private void Home_Button_Click(object sender, RoutedEventArgs e)
{
}
}
For some reason my design window for "ThisControl.xaml" is not showing anything.
My "ThisControl.xaml.cs" file looks like this:
public partial class ThisControl : UserControl
{
public ThisControl()
{
InitializeComponent();
}
private void InitializeComponent()
{
}
}
And I have the "DropDownButtonBehavior.cs" code from above. And I also have the "ThisControl.XAML" code from above.
Thanks a lot
Really great! I tested some other stuff like this.. yours is the best, it is themes compatible, and use the best and nicer way to do the trick. Thank you again!