Freigeben über


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 Fabio

  • Anonymous
    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 again

  • Anonymous
    June 18, 2010
    Fabio, Two things to check:

  1. When you made that change to generic.xaml, did you do it for both SplitButton and MenuButton?
  2. 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 Fabio

  • Anonymous
    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! Fabio

  • Anonymous
    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 removed

  • Anonymous
    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 removed

  • Anonymous
    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 you

  • Anonymous
    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! :)