1

I'm trying to figure hot to bind commands from ribbon to content control.

My view look something like this:

  <Window.Resources>
    <DataTemplate DataType="{x:Type VM:CityViewModel}">
        <Views:EditorView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type VM:CountryViewModel}">
      <Views:EditorView />
    </DataTemplate>
    <DataTemplate DataType="{x:Type VM:SomeOtherViewModel}">
      <Views:SomeOtherView />
    </DataTemplate>
  </Window.Resources>
 <DockPanel>
    <Fluent:Ribbon x:Name="MainRibbon"
                   AutomaticStateManagement="True"
                   DockPanel.Dock="Top">
      <Fluent:RibbonTabItem Header=SomeHeader>
      <Fluent:RibbonGroupBox Header="Actions">
       <Fluent:Button Fluent:RibbonAttachedProperties.RibbonSizeDefinition="Middle,Small"
                      Header="New"
                      Command = "{Binding NewCommand}"
                      CommandTarget="{Binding ElementName=SubView}"/>
       <Fluent:Button Fluent:RibbonAttachedProperties.RibbonSizeDefinition="Middle,Small" Header="Save"
                      Command = "{Binding SaveCommand}"
                      CommandTarget="{Binding ElementName=SubView}"/>
      </Fluent:RibbonGroupBox>
     </Fluent:RibbonTabItem>
   </Fluent:Ribbon>           
  <ContentControl Name="SubView" Content="{Binding CurentSubView}" />
 </DockPanel>

MainViewModel sets CurrentSubView from IOC:

CurentSubView = ViewModelFactory.Create<SomeViewModel>();

CityViewModel and CountryViewModel are derived from EditorViewModel<T> And share basic Actions which have been put to EditorViewModel<T> base class

 public RelayCommand NewCommand { get; private set; }
 public RelayCommand SaveCommand { get; private set; }

etc....

The question for me is how to expose commands from child viewmodel to ribbon?

As first view model CurrentSubView does not implement those commands so I get "BindingExpression path error: 'NewCommand' property not found on 'object' ''MainViewModel'".....

I managed to bind command by some code in my MainViewModel i have added:

 private RelayCommand m_newCommand;
 public RelayCommand NewCommand
   {
     get { return m_newCommand; }
   }
  if (typeof(IEditorViewModel).IsInstanceOfType(CurentSubView))
  {
    m_newCommand = ((IEditorViewModel)CurentSubView).NewCommand;
    RaisePropertyChanged(() => NewCommand);
  }
  else
  {
    m_newCommand = null;
  }

But still opened for more elegant suggestions ;)

Tomislav
  • 153
  • 3
  • 15
  • So CityViewModel and CountryViewModel are instantiated in CurrentSubView? Can you set the DataContext of the Fluent:Ribbon to use the correct ViewModel? – Jason Massey Nov 05 '13 at 18:41
  • Yes but only only on button click like `` and command OpenView is RelayCommand on MainViewModel and this works – Tomislav Nov 05 '13 at 18:44
  • This looks similar to what you need. http://stackoverflow.com/questions/1026342/how-can-i-tell-my-datatemplate-to-bind-to-a-property-in-the-parent-viewmodel?rq=1 – Jason Massey Nov 05 '13 at 19:17
  • Yes it is similar to that question but in reverse order Child->Parent. I need Parent-Child command binding – Tomislav Nov 05 '13 at 22:23
  • If you have multiple chile, how should the parent know which child command should be executed? – Lance Nov 08 '13 at 00:54
  • MainViewModel at the given moment holds only one active SubViewModel visible so after SubViewModel is taken from IOC I will have a method to bind commands from tab to activated SubViewModel. Only one "RibbonTab" with commands that are shared can be active so it's easy but a lot of possible ugly code :(. Swithing between SubViewModels also include rebinding commands – Tomislav Nov 08 '13 at 13:13

1 Answers1

0

So it was simple as it can be. <fluent:RibbonTabItem/> has it's on DataContext So only needed to be done:

<fluent:RibbonTabItem Name="SomeTab" DataContext="{Binding CurrentViewModel}" Header="SomeTab">
Tomislav
  • 153
  • 3
  • 15