SplitButtoning hairs [Two fixes for my Silverlight SplitButton/MenuButton implementation - and true WPF support]
**
This blog has moved to a new location and comments have been disabled.
All old posts, new posts, and comments can be found on The blog of dlaa.me.
See you there!
Comments
Anonymous
June 13, 2010
Hi David, You're SplitButton is absolutly awsome. I 'm using it on different project and the only problem i 've encountering, was about Zoom. Now, all is perfect ! Thanks a lot !Anonymous
June 14, 2010
Samuel, Thanks for the kind words! :)Anonymous
June 15, 2010
Hi David, your Control is beautiful but it's not responding to command properly (WPF version). Menu items appear always grayed out. is this a bug? thanks FabioAnonymous
June 16, 2010
Fabio, I just tried this and found a problem that may be what you're seeing as well. The ContextMenu (on WPF; I haven't tried on Silverlight) isn't inheriting the DataContext from the SplitButton parent, so the Command Bindings on the MenuItem don't map to anything and aren't hooked up right. I'd expect this to leave the MenuItems in the default IsEnabled=true state, but maybe you're changing that? At any rate, adding the following to the list of properties for the ContextMenu element inside the SplitButton/MenuButton Template in Generic.xaml fixed the problem I was seeing: DataContext="{TemplateBinding DataContext}" This is probably a good change to make anyway, but I'm not certain it will fix the problem you're seeing. If you wouldn't mind trying this out and letting me know, I'd appreciate it. Thanks!Anonymous
June 17, 2010
Hi David, thanks for your fast reply. i've tryed oot your suggestion but nothing changed. here the fragments: my xaml: <localcontrols:MenuButton x:Name="DropTermButton" Content="Drop" Padding="4,1" Margin="4,0,0,0" Command="localclasses:MyCommands.Drop"> <localcontrols:MenuButton.ButtonMenuItemsSource> <MenuItem Header="Term only" Command="localclasses:MyCommands.DropTerm" /> <MenuItem Header="Term and narrowers" Command="localclasses:MyCommands.DropTermTree" /> </localcontrols:MenuButton.ButtonMenuItemsSource> </localcontrols:MenuButton> generic.xaml: <ContextMenuService.ContextMenu> <ContextMenu ItemsSource="{Binding ButtonMenuItemsSource, RelativeSource={RelativeSource TemplatedParent}}" Foreground="{TemplateBinding Foreground}" FlowDirection="{TemplateBinding FlowDirection}" DataContext="{TemplateBinding DataContext}" /> </ContextMenuService.ContextMenu> thanks againAnonymous
June 18, 2010
Fabio, Two things to check:
- When you made that change to generic.xaml, did you do it for both SplitButton and MenuButton?
- Try removing the Command binding on MenuButton itself - I'm not sure what effect it would have, and it doesn't fit with my idea of how MenuButton should behave (always show the menu). If neither of those helps, could you please create a small, self-contained sample and send it to me via the "Email Blog Author" link? The answer may depend on something specific about your scenario that isn't true for my simple test case. Thanks!
Anonymous
June 24, 2010
hi David, neither of your suggestions worked for me. i've packed up a very simple project that look like the more complex one. i've posted it to skydrive. here's the link: cid-3c018077b51a3ea8.office.live.com/.../MenuButtonSample.zip thanks in advance FabioAnonymous
June 25, 2010
Fabio, Thank you - I'll try to have a look at your sample in the next couple of days and let you know what I find.Anonymous
June 27, 2010
Fabio, I've looked at this a bit just now and I can tell you WHY it's not working - though I don't yet know how to fix it. :| What you're seeing is similar to the DataContext issue I identified above - but things are different for your scenario because you're using RoutedCommands instead of Bindings to ICommand implementations. What seems to be the case in your example is that the ContextMenu for the SplitButton doesn't have the main Window instance as a logical ancestor - so the RoutedCommands you've hooked up to your MenuItems don't bubble all the way up to the handlers you've attached to the main Window instance. I find that if I call AddLogicalChild from the SplitButton's handler for ContextMenu.Opened to set the Popup parent of the ContextMenu as a logical child of the SplitButton instance, the CanExecute handlers you've defined suddenly start getting called like we want! However, once I've made that change, the ContextMenu suddencly starts dismissing itself immediately after opening... So this is progress, but not quite all the way to a working solution. I'll keep looking into this, but wanted to give you an update now that I knew something more. Thanks for your patience!Anonymous
June 28, 2010
David, thank you so much! FabioAnonymous
June 30, 2010
Fabio, I think I have fixed the problem. :) Could you please contact me via http://cesso.org/r/Email and I'll reply with the new code so you can try it out yourself? If you confirm the fix, I'll blog it in the next couple of days and credit you for the bug report. Thanks for your help!Anonymous
July 22, 2010
Hi, I read through the last few posts. Wondering if you have posted up any new code that will work with MVVM? I tried with: <common:IconButton IconImage="Save" Command="{Binding OptionClick}" Height="22" HorizontalAlignment="Left" Name="iconButton1" VerticalAlignment="Top" ToolTipService.ToolTip="Create New Row" > <common:SplitButton.ButtonMenuItemsSource> <toolkit:MenuItem Header="Option1" Command="{Binding OptionClick}"/> <toolkit:MenuItem Header="Option2" /> <toolkit:MenuItem Header="Option3" /> </common:SplitButton.ButtonMenuItemsSource> </common:IconButton> But it is not responding to my commands similar to the above... Thanks!Anonymous
July 23, 2010
The comment has been removedAnonymous
September 01, 2010
Great split button and thanks for the posts. Any thoughts on supporting toolkit themes?Anonymous
September 01, 2010
Joey, Thanks! I'm probably not going to do additional themes myself, but if someone did, I'd be happy to link to their work. :)Anonymous
October 16, 2010
The comment has been removedAnonymous
October 18, 2010
John Langley, Thanks for the compliments! When commanding, it's common to use a dedicated command implementation for each "function". For example, there might be a command for Printing and it will be hooked up to the File/Print option and a Toolbar button and the Ctrl+P accelerator - and because they're all supposed to print, it doesn't care which one triggered it - it just prints. :) Where things get a little different is when you have a command in a ListBox for something like "remove" and all the items look the same. In this case, I might use the CommandParameter property to pass in some item-specific information that the command implementation can then use to determine which specific item needs to be dealt with. Hope this helps!Anonymous
October 20, 2010
Great SplitButton, the easiest I have seen so far. But I have a question regarding the MenuItem-part: I don't know my MenuItems in designtime so I cannot write them manual in xaml. So I thought about binding a ObservableCollection of MenuItems (including ICommands and all that stuff) from my ViewModel, because I hold all the Information in a Collection anyway. But how to do bind to the Button? ButtonMenuItemsSource is not suited for binding. I would be glad if you could help me with this! :) I have constant battles with all kind of SplitButtons for a while now and it seems that ContextMenus try to wear me down. ;)Anonymous
October 21, 2010
Oh, sorry, I was so stupid :) Of course I just had to change ButtonMenuItemsSource into a DependencyProperty and everything is fine! Thank you for such a nice and easy-to-use control! :)Anonymous
October 21, 2010
Amaryllion, I'm glad you got that sorted out - I'm sorry for the trouble! In case it helps you feel better, making that very change is on my TODO list for a future release of SplitButton. :) PS - Thanks for the kind words!Anonymous
December 05, 2010
Hi David, Thank you for this control. I want to report a bug: The SplitButton control paced in a ChildWindow - SL4 - strange behaviour: the drop down section is out of place. Any idea ? Thank youAnonymous
December 05, 2010
Hi - more info about: "The SplitButton control paced in a ChildWindow - SL4 - strange behaviour: the drop down section is out of place.". The problem appear only if Zoom Level (applied by IE) != 100 and SplitButton control paced in a ChildWindow;Anonymous
December 06, 2010
rlodina, I think I've heard of other issues with controls inside a ChildWindow at non-100% browser zoom levels. I haven't looked into this specifically, but my guess would be that something about ChildWindow affects how otherwise correctly-functioning controls operate (possibly the Popup or the centering mechanism?). If someone can identify why that is, it might help here...Anonymous
September 25, 2011
this is a great set of extensions. Could you point me in the right direction to find what I need to update in the templates to have the control toolkit's styles picked up in these controls?Anonymous
September 26, 2011
Kyle, Thanks! :) Unfortunately, the templating story for XAML doesn't make this task as easy as it could be. Basically, each theme's template contains a complete definition of the control's UI, so if you want to create a SplitButton using the "Whistler Blue" theme (or whatever), you'll need to start from the Button template for that theme. Fortunately, those templates are available via Blend's Edit Template feature or in source form as part of the Silverlight Toolkit download. The steps to customize a Button template for for SplitButton are quite simple - I outlined them in the original post: blogs.msdn.com/.../developer-test-case-customer-win-using-contextmenu-to-implement-splitbutton-and-menubutton-for-silverlight-or-wpf.aspx Hope this helps!Anonymous
November 10, 2011
I found that the contextmenu offset was still wrong when the split button was on a childwindow. I added the following scaling which seems to have fixed it: _contextMenu.HorizontalOffset = ( desiredOffset.X - currentOffset.X ) * Application.Current.Host.Content.ZoomFactor; _contextMenu.VerticalOffset = ( desiredOffset.Y - currentOffset.Y ) * Application.Current.Host.Content.ZoomFactor;Anonymous
November 10, 2011
Mark, That's great, thank you for sharing! :)Anonymous
July 17, 2012
Hi David, tried your sample in SL5 and the context menu position is not displayed under the button anymore. Do you have a sample working for SL5? Thanks.Anonymous
July 17, 2012
Migus, Sorry, I don't have a Silverlight 5 version handy. :( If you find out what's broken with that platform and are able to follow-up here, that would be much appreciated!Anonymous
July 26, 2012
Hey David, I am using the SplitButton in a WPF .NET 4.0 application (it is the child of a stackpanel in a window). For some reason, the context menu (without any interaction) initially pops up in the top right corner of my primary monitor when the window is instantiated. It disappears after a couple seconds then all is well. Any idea why this occurs? -Thanks. Great blog by the way! I am also utilizing your VirtualFile stuff for Drag and Dropping to windows :)Anonymous
July 26, 2012
Chevon, I'm not sure why that should happen... You might try setting a couple of breakpoints to see if the code to show the ContextMenu is getting triggered somehow. I don't recall that being a problem with the sample application, so maybe it has something to do with how your app is structured? PS - Thanks for the kind words! :)