1

I have a TvShowsViewModel (1) that contains an ObservableCollection of TvShowViewModels (2). A TvShowViewModel contains an ObservableCollection of SeasonViewModels (3).

I have a TreeView, which has the TvShowsViewModel (1) as DataContext. The ItemSource of that TreeView binds to the ObservableCollection of TvShowViewModels (2).

The TreeView specifies a HierarchicalDataTemplate, which binds to the ObservableCollection of SeasonViewModels (3).

The HierarchicalDataTemplate contains a ContextMenu.

Now, the ContextMenu contains a Command which I want to bind to a RelayCommand in the TvShowsViewModel (1).

I tried all kinds of RelativeSource bindings, but nothing that leads to the solution. How should I specify the binding?

TvShowsViewModel (1)

public class TvShowsViewModel : ViewModelBase
{
    public RelayCommand ExcludeSeasonCommand { get; private set; }

    public ObservableCollection<TvShowViewModel> TvShows { get; private set; }

    public TvShowsViewModel(ITvShowsLibrary tvShowsLibrary)
    {
        TvShows = new ObservableCollection<TvShowViewModel>();

        ExcludeSeasonCommand = new RelayCommand(ExcludeSeasonCommandOnExecute, ExcludeSeasonCommandOnCanExecute);

    // Left out irrelevant code
    }
}

TvShowViewModel (2)

public class TvShowViewModel : ViewModelBase, IFolderOnDisk
{
    public ObservableCollection<SeasonViewModel> Seasons
    {
        get { return _seasons; }
    }

    // Left out irrelevant code
}

SeasonViewModel (3)

public class SeasonViewModel : ViewModelBase, IFolderOnDisk
{
    // Left out irrelevant code
}

The stripped user control (TreeView)

<!-- Again, left out a lot of irrelevant parts -->
<TreeView ItemsSource="{Binding TvShows}">

    <TreeView.ItemTemplate>
        <HierarchicalDataTemplate DataType="tvShows:TvShowViewModel" ItemsSource="{Binding Seasons}">
            <TextBlock Text="{Binding Name}" />

            <HierarchicalDataTemplate.ItemTemplate>
                <HierarchicalDataTemplate>
                    <TextBlock Text="{Binding Name}">
                        <TextBlock.ContextMenu>
                            <ContextMenu>
                                <MenuItem
                                    Header="Exclude season"
                     <!-- This is where I need your help, how should I configure the binding? -->
                                    Command="{Binding Path=DataContext.ExcludeSeasonCommand, RelativeSource={RelativeSource AncestorType=TreeView}}" />
                            </ContextMenu>
                        </TextBlock.ContextMenu>
                    </TextBlock>
                </HierarchicalDataTemplate>
            </HierarchicalDataTemplate.ItemTemplate>
        </HierarchicalDataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

The binding, which I can't figure out

1 Answer 1

7

Finally, after many many many google searches I ran into the solution

<MenuItem
    Header="Exclude season"
    Command="{Binding DataContext.ExcludeSeasonCommand, Source={x:Reference _tvShowsTreeView}}" />

Because the HierarchicalDataTemplate does not appear in the visual tree, there is not "relative" source...

I hope this helps somebody else who's pulling his/her hair out...

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks! Saved some of my hair! Note you need to give the TreeView a Name to use as the x:Reference.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.