How to bind a ComboBox on the ribbon to a property in the view model of a Docking Window

Ribbon for WPF Forum

Posted 7 years ago by Tony Pulokas
Version: 12.1.0561
Avatar

I have already already developed some ribbon buttons that execute commands on the view model of a Docking Window through the use of Prism CompositeCommands and DelegateCommands.  This seems to be working very well.  However, now I am very lost in trying to figure out how a ComboBox (or a TextBox) on the ribbon could be bound to the view model of the active window. 

I read the page about "Interaction with Value Controls" in the documentation, and I think I understand how that is supposed to work after viewing "RichTextBoxExtended.cs" in the code samples.  However, this sample does not involve docking windows.  There is another sample under the "Docking & MDI" product family, that I can get to by clicking "RibbonWindow with Docking".  Although this sample purports to show how to use a ribbon with docking, the ComboBoxes (like the one for Font Size) aren't functional.  In the Rich Text Box sample, if I put the cursor on some text, the Font Size ComboBox automatically updates to reflect the font size of the selected text.  In the Docking example, this ComboBox doesn't do anything at all.  As far as I can tell, the code for it is simply incomplete, and isn't helpful.  However, the fact that you have a sample like this seems to imply that you can put a ComboBox on a Ribbon with Docking Windows.

How can I get the effect of having my ComboBox's SelectedItem being bound to a property in the ViewModel of a Docking Window? And are there any examples I can study?

Comments (3)

Posted 7 years ago by Tony Pulokas
Avatar

OK, I've continued to experiment and I think I'm close to the answer.  In the view model, I created a DelegateCommand<T> like so:

        private DelegateCommand<ObjectValueCommandParameter> _plotContainerGridColumnCountCommand;
        public DelegateCommand<ObjectValueCommandParameter> PlotContainerGridColumnCountCommand
        {
            get
            {
                if (_plotContainerGridColumnCountCommand == null)
                    _plotContainerGridColumnCountCommand = new DelegateCommand<ObjectValueCommandParameter>
                            (OnNumberOfPlotColumnsExecute, OnNumberOfPlotColumnsCanExecute);
                return _plotContainerGridColumnCountCommand;
            }
        }
        public void OnNumberOfPlotColumnsExecute(ObjectValueCommandParameter value)
        {
            // view model receives the value from the view
            PlotContainerGridColumnCount = int.Parse(value.Value.ToString());
        }
        public bool OnNumberOfPlotColumnsCanExecute(ObjectValueCommandParameter value)
        {
            // provide the value from the view model to the view
            value.Value = PlotContainerGridColumnCount.ToString();
            return true; 
        }

 And in the XAML for the ribbon:

                    <ribbon:ComboBox DockPanel.Dock="Left" x:Name="NumberOfColumnsComboBox"
                              Command="{x:Static modules:GlobalCommands.PlotContainerGridColumnCountCommand}">
                        <ComboBoxItem>1</ComboBoxItem>
                        <ComboBoxItem>2</ComboBoxItem>
                        <ComboBoxItem>3</ComboBoxItem>
                        <ComboBoxItem>4</ComboBoxItem>
                        <ComboBoxItem>5</ComboBoxItem>
                    </ribbon:ComboBox>

Where GlobalCommands.PlotContainerGridColumnCountCommand is a CompositeCommand that has registered PlotContainerGridColumnCountCommand that is in the view model.

I set breakpoints while debugging, so I can see that both of the OnExecute and OnCanExecute methods are being called.  The view model property is appropriately being assigned when the ComboBox's selection is changed.  However, the value I assign in the OnCanExecute method isn't showing up in the ComboBox.  Clearly I have more to figure out here, but I wanted to post right away to say that I don't think I'm totally in the dark anymore.

Answer - Posted 7 years ago by Tony Pulokas
Avatar

The following revision to my view model code seems to be working great

    private DelegateCommand<ObjectValueCommandParameter> _plotContainerGridColumnCountCommand;
    public DelegateCommand<ObjectValueCommandParameter> PlotContainerGridColumnCountCommand
    {
        get
        {
            if (_plotContainerGridColumnCountCommand == null)
                _plotContainerGridColumnCountCommand
                        = new DelegateCommand<ObjectValueCommandParameter>
                            (OnNumberOfPlotColumnsExecute, OnNumberOfPlotColumnsCanExecute);
            return _plotContainerGridColumnCountCommand;
        }
    }
    public void OnNumberOfPlotColumnsExecute
        (ObjectValueCommandParameter commandParameter)
    {
        // view model receives the value from the view
        int newValue = int.Parse(commandParameter.Value.ToString());
        if(PlotContainerGridColumnCount != newValue)
            PlotContainerGridColumnCount = newValue;
    }
    public bool OnNumberOfPlotColumnsCanExecute
        (ObjectValueCommandParameter commandParameter)
    {
        // provide the value from the view model to the view
        commandParameter.UpdatedValue = PlotContainerGridColumnCount.ToString();
        commandParameter.Handled = true;
        return true; 
    }
Posted 7 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Tony,

Yes it looks like what you set up is correct.  I'm glad you got it working.


Actipro Software Support

The latest build of this product (v2019.1 build 0681) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.