Доступ к ViewModel / DataConext внутри ContextMenu - PullRequest
5 голосов
/ 26 июля 2011

Как я могу получить оригинальный DataContext из UserControl внутри ContextMenu.

Приведенный ниже код показывает, что в шаблоне данных есть кнопка, которая правильно связывается. Однако при попытке связать источник данных контекстного меню я получаю следующую ошибку:

System.Windows.Data Ошибка: 4: Не удается найти источник для привязки со ссылкой 'RelativeSource FindAncestor, AncestorType =' System.Windows.Controls.TreeView ', AncestorLevel =' 1 ''. BindingExpression: Path = DataContext; DataItem = NULL; целевым элементом является ContextMenu (Name = ''); Свойство target - «DataContext» (тип «Object»)

Что мне нужно сделать, чтобы ContextMenu связывался с ViewModel?

=============================================== ================================

ViewModel назначается текстовому тексту представления в кодовой области:

Вид:

<TreeView ItemsSource="{Binding Clients}"
          cmd:TreeViewSelect.Command="{Binding SelectionChangedCommand}"
          cmd:TreeViewSelect.CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=SelectedItem}">
    <TreeView.ItemTemplate>
        <DataTemplate>
            <StackPanel>
                <TextBlock Text="{Binding Name}">
                    <TextBlock.ContextMenu>
                        <ContextMenu DataContext="{Binding DataContext, 
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeView}}}">
                            <MenuItem Header="{Binding TestString}" />
                        </ContextMenu>
                    </TextBlock.ContextMenu>
                </TextBlock>

                <Button  DataContext="{Binding DataContext, 
                            RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type TreeView}}}"
                         Content="{Binding TestString}" Command="{Binding EditSelectedClientCommand}" />
             </StackPanel>
        </DataTemplate>
    </TreeView.ItemTemplate>
</TreeView>

ViewModel:

public class ClientListViewModel : ViewModelBase
{
    public String TestString { 
        get {
            return "TESTING";  
        }
    }

    private ClientList _clients = null;
    private readonly IClientService _clientService = null;
    private readonly IEventAggregator _eventAggregator = null;
    private Client _selectedClient = null;
    private ICommand _selectionChangedCommand = null;
    private ICommand _editSelectedClientCommand = null;
    ....
}

1 Ответ

9 голосов
/ 26 июля 2011

ContextMenus не отображаются в визуальном дереве, что приводит к сбою привязок RelativeSource, однако вы все равно можете получить DataContext так или иначе. Вы можете попробовать это, например:

<TextBlock Text="{Binding Name}"
           Tag="{Binding DataContext, RelativeSource={RelativeSource AncestorType=TreeView}}">
    <TextBlock.ContextMenu>
        <ContextMenu DataContext="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource Self}}">
            <MenuItem Header="{Binding TestString}" />
            <!-- ... --->

PlacementTarget - это текстовый блок, а DataContext проходит через Tag. Только один способ сделать это (по крайней мере, я надеюсь, что это работает), я также видел некоторые библиотеки, которые по-разному преодолевают этот разрыв, но я не помню их происхождение ...

...