In your MainViewModel create a property to hold the RadioControlViewModel and one to hold the selected OptionViewModel. In your constructor, register for the OptionSelectionChanged event of the RadioControlViewModel. The EventHandler method should change the value of OptionViewModel to an instance of a ViewModel representing the control you wish to show for that selection. All comments in code stating "etcetera" means to add the same preceeding code for option 3 & 4.
MainViewModel
public class MainViewModel
{
private RadioControlViewModel _rcViewModel;
public RadioControlViewModel RcViewModel
{
get { return _rcViewModel; }
set
{
_rcViewModel = value;
RaisePropertyChanged("RcViewModel");
}
}
private OptionViewModelBase _optionViewModel;
public OptionViewModelBase OptionViewModel
{
get { return _optionViewModel; }
set
{
_optionViewModel = value;
RaisePropertyChanged("OptionViewModel");
}
}
public MainViewModel()
{
RcViewModel = new RadioControlViewModel();
RcViewModel.OptionSelectionChanged += RcViewModel_OptionSelectionChanged;
}
private void RcViewModel_OptionSelectionChanged(object sender, OptionSelectionChangedEventArgs e)
{
if (e.Selection == null)
{
OptionViewModel = null;
return;
}
switch (e.Selection)
{
case Option.OptionOne:
OptionViewModel = new OptionOneViewModel();
break;
case Option.OptionTwo:
OptionViewModel = new OptionTwoViewModel();
break;
// etcetera
}
}
}
In your MainView.Resources, you'll place DataTemplates mapping each OptionViewModel to the corresponding OptionView. The first StackPanel has your RadioControlView with it's DataContext bound to the RadioControlViewModel property of your MainViewModel. In the second StackPanel, you use a ContentPresenter and bind the Content property to the OptionViewModel property of the MainViewModel. The DataTemplates will tell it how to present this.
MainView
<Window.Resources>
<DataTemplate DataType="{x:Type viewmodel:OptionOneViewModel}">
<view:OptionOneView />
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodel:OptionTwoViewModel}">
<view:OptionTwoView />
</DataTemplate>
<!-- etcetera -->
</Window.Resources>
<Grid>
<StackPanel>
<view:RadioControlView DataContext="{Binding RcViewModel}" />
</StackPanel>
<StackPanel>
<ContentPresenter Content="{Binding OptionViewModel}" />
</StackPanel>
</Grid>
The RadioControlViewModel will have a OptionSelectionChanged event that it raises whenever one of the bound RadioButtons set their property to true.
RadioControlViewModel
public class RadioControlViewModel
{
public event EventHandler<OptionSelectionChangedEventArgs> OptionSelectionChanged;
private bool _optionOneSelected;
public bool OptionOneSelected
{
get { return _optionOneSelected; }
set
{
_optionOneSelected = value;
RaisePropertyChanged("OptionOneSelected");
if (value)
RaiseOptionSelectionChanged(Option.OptionOne);
}
}
private bool _optionTwoSelected;
public bool OptionTwoSelected
{
get { return _optionTwoSelected; }
set
{
_optionTwoSelected = value;
RaisePropertyChanged("OptionTwoSelected");
if (value)
RaiseOptionSelectionChanged(Option.OptionTwo);
}
}
// etcetera
private void RaiseOptionSelectionChanged(Option selection)
{
var handler = OptionSelectionChanged;
if (handler == null)
return;
handler(this, new OptionSelectionChangedEventArgs(selection));
}
}
The preceeding code is assuming that you'll create an OptionSelectionChangedEventArgs class and have an enum called Option. There will be some tweaks needed such as your MainViewModel constructor will probably want to set the OptionViewModel property to whichever Option will initialize as selected.