I want to bind the content of my TabControl
to an instance of my StepViewModel
in a ObservableCollection
Steps.
My ProcessViewModel:
pubic class ProcessViewModel : ViewModelBase
{
public ObservableCollection<StepViewModel> Steps
{
get { return _steps; }
set { _steps = value; OnPropertyChanged("Steps"); }
}
public StepViewModel SelectedStep
{
// like above...
}
}
My StepViewModel (DataContext should be the StepVMs in Steps of ProcessVM):
public class StepViewModel : ViewModelBase
{
public string Name { get {...} set {...} }
public object Media { get {...} set {...} }
//...
}
My TabControl (DataContext is ProcessViewModel):
<C1:C1TabControl
ItemsSource="{Binding Steps}"
SelectedItem="{Binding SelectedStep}"
SelectionChanged="{tcSteps_OnSelectionChanged">
<C1:C1TabControl.ContentTemplate>
<DataTemplate>
<local:StepView
DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type vmns:ProcessViewModel}}, Path=SelectedStep}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</local:StepView>
</DataTemplate>
</C1:C1TabControl.ContentTemplate>
</C1:C1TabControl>
The Compiler delivers the following output message:
"System.Windows.Data Error: 40 : BindingExpression path error: 'SelectedStep' property not found on 'object' ''StepViewModel' (HashCode=32952144)'. BindingExpression:Path=SelectedStep; DataItem='StepViewModel' (HashCode=32952144); target element is 'StepView' (Name='StepView'); target property is 'DataContext' (type 'Object')"
Does anyone know how I can solve the? Thanks!
It looks like there could be a few small issues with the RelativeSource on your DataContext binding for the StepView. Since the template is not part of the visual tree, I don't think you can use FindAncestor. You can use a StaticResource as a pointer to your main DataContext (eg http://www.codeproject.com/Articles/27432/Artificial-Inheritance-Contexts-in-WPF), but I think it might be simpler to just search by ElementName instead in this case. That method would look something like this:
Update your TabControl to have a name, so it is searchable in bindings by ElementName
<C1:C1TabControl
x:Name="MyTabControl"
ItemsSource="{Binding Steps}"
SelectedItem="{Binding SelectedStep}"
SelectionChanged="{tcSteps_OnSelectionChanged">
Update your StepView to look for the TabControl's DataContext by ElementName
<local:StepView DataContext="{Binding ElementName=MyTabControl, Path=DataContext.SelectedStep}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
</local:StepView>