Search code examples
mvvmdependency-injectionunity-containeravalondockconstructor-injection

Injecting Instantiated ViewModel to View with AvalonDock


I have an Observable Collection of ViewModels that are bound to the AvalonDock's LayoutItemTempate. When the user opens a problem from a fetched list, it creates a new ViewModel in the observable collection. A new document is created as a result, but it is new and does not use the ViewModel from the collection.

I tried to use a converter, but it doesn't seem to use the converter at all. Does anyone know an alternative? Perhaps even a code-behind solution?

Here is the main XAML snippet . . .

 <Window.Resources>
    <pconv:IProblemInfoToFreeResponseVMConverter x:Key="FreeResponseToVM" />
</Window.Resources>
. . . { some lines down } . .  .
<dock:DockingManager.LayoutItemTemplateSelector>
    <selector:LayoutItem>
        <selector:LayoutItem.ProblemEditViewTemplate>
            <DataTemplate>
                <problem:FreeResponseEdit 
                    DataContext="{Binding SelectedProblem,
                        Converter={StaticResource FreeResponseToVM}}" />
            </DataTemplate>
        </selector:LayoutItem.ProblemEditViewTemplate>
    </selector:LayoutItem>
</dock:DockingManager.LayoutItemTemplateSelector>

my Converter code . . .

[ValueConversion(typeof(FreeResponse), typeof(FreeResponseEditViewModel))]
public class IProblemInfoToFreeResponseVMConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is FreeResponse)
            return new FreeResponseEditViewModel(value as FreeResponse);
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is FreeResponseEditViewModel)
            return (value as FreeResponseEditViewModel).ProblemItem;
        return value;
    }
}

Solution

  • Binding ItemSource to a stack of FreeResponseEditViewModel, the DataTemplate creates FreeResponseEdit and then injects the FreeResponseEditViewModel into the view as a DataContext automatically.

    <dock:DockingManager.LayoutItemTemplateSelector>
        <selector:LayoutItem>
            <selector:LayoutItem.ProblemEditViewTemplate>
                <DataTemplate>
                    <problem:FreeResponseEdit /> 
                </DataTemplate>
            </selector:LayoutItem.ProblemEditViewTemplate>
        </selector:LayoutItem>
    </dock:DockingManager.LayoutItemTemplateSelector>
    

    The DataContext is omitted altogether.