简体   繁体   中英

Bind ContextMenu Command to parents viewmodel RelayCommand

I have a TvShowsViewModel (1) that contains an ObservableCollection of TvShowViewModel s (2). A TvShowViewModel contains an ObservableCollection of SeasonViewModel s (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

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...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM