Search code examples
wpfribbonreactiveui

How to use a RibbonGallery with a RibbonComboBox


So I wanted to add a RibbonCombobox to my Ribbon in WPF. For some reason, RibbonCombobox does not have a selectionchanged event. I read that you should use a RibbonGallery for selection change event so I implemented this

 <RibbonComboBox   Label="Equations" x:Name="EquationListComboToolbar"  ItemsSource="{Binding}">
                            <RibbonGallery x:Name="EquationListComboboxGallery" SelectedValue="{Binding  XPath=.}" />
                        </RibbonComboBox>

Behind the scene the binding is done like this.

  EquationListComboToolbar.DataContext = ViewModel.EquationNames;
                this.Bind(ViewModel, vm => vm.SelectedEquation, v => v.EquationListComboboxGallery.SelectedItem).DisposeWith(cleanup);
                Observable.FromEventPattern(EquationListComboboxGallery, nameof(EquationListComboboxGallery.SelectionChanged)).Subscribe(e => ViewModel.SelectEquation(EquationListComboboxGallery.SelectedItem?.ToString()));

At runtime I get the following error

"An unhandled exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll Items collection must be empty before using ItemsSource." When the app initalizez. I know it's something about the Gallery but I can't figure out what is the problem and how can I achieve this.

As I was suggested, I already tried the answer that was suggested

 <RibbonComboBox   Label="Equations" x:Name="EquationListComboToolbar"  ItemsSource="{Binding}">
                            <RibbonComboBox.ItemTemplate>
                                <DataTemplate>
                                    <RibbonGallery x:Name="EquationListComboboxGallery" SelectedValue="{Binding  XPath=.}" />
                                </DataTemplate>
                            </RibbonComboBox.ItemTemplate>
                        </RibbonComboBox>

Doing this, will make by binding imposible

enter image description here


Solution

  • Ah, yes. The Microsoft ribbon library is lots of fun. Luckily I've been down this road before. Here's a working example of a RibbonComboBox from one of my applications, complete with RibbonGallery:

    <RibbonComboBox DropDownHeight="400">
        <RibbonGallery MaxColumnCount="1" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedItem="{Binding MySelectedItemProperty}">
            <RibbonGalleryCategory ItemsSource="{Binding MyItemsSourceProperty}"/>
        </RibbonGallery>
    </RibbonComboBox>
    

    I'm not entirely sure this is the only way to do things, but I know this way works. Note that I set ItemsSource on the RibbonGalleryCategory, not the RibbonComboBox itself. It might be possible to use the RibbonGallery without a RibbonGalleryCategory, in which case you would set ItemsSource on RibbonGallery, but I've not tested this.

    Note you also have the ability to add multiple galleries categories to a single RibbonComboBox like so:

    <RibbonComboBox DropDownHeight="400">
        <RibbonGallery MaxColumnCount="1" ScrollViewer.VerticalScrollBarVisibility="Auto" SelectedItem="{Binding MySelectedItemProperty}">
            <RibbonGalleryCategory ItemsSource="{Binding MyFirstItemsSourceProperty}"/>
            <Separator/>
            <RibbonGalleryCategory ItemsSource="{Binding MySecondItemsSourceProperty}"/>
        </RibbonGallery>
    </RibbonComboBox>
    

    The above lets you show multiple lists in the same drop down and allows the user to select a single item from any list. Functionality like this is probably why RibbonGalleryCategory exists in the first place.