2011-07-26 5 views
5

ContextMenu内のUserControlの元のDataContextを取得する方法を教えてください。ContextMenu内のViewModel/DataConextへのアクセス

次のコードは、正しくバインドするDataTemplateのボタンがあることがわかります。コンテキストメニューのデータソースをバインドしようとしたときしかし、私は次のエラーを受け取る:

System.Windows.Dataエラー:4:参照「RelativeSource FindAncestor、AncestorType =」System.Windowsとの結合のためのソースを見つけることができません。 Controls.TreeView '、AncestorLevel =' 1 ''となります。 BindingExpression:Path = DataContext; DataItem = null;ターゲット要素は 'ContextMenu'(Name = '');対象のプロパティが 'DataContext'(タイプ 'Object')

ContextMenuをViewModelにバインドするにはどうすればよいですか?

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

ビューモデルは、分離コードのビューのDataContextのに割り当てられています:

ビュー:

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

答えて

9

ContextMenusは、RelativeSource-bindingsが失敗するビジュアルツリーには表示されませんが、どちらか一方の方法でも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はTextBlockのある、そしてDataContextTagを介してトンネリングされます。これを行うためのただ一つの方法は、(少なくとも私はそれが動作を期待)、私はまた違った橋、このギャップいくつかのライブラリを見てきましたが、私はこれは素晴らしい仕事を

+0

...彼らの起源を覚えていません!ありがとうございました!あなたはこのギャップを橋渡しするかもしれない他のライブラリについて言及しましたが、プリズムはこれらの一つでしょうか? –

+0

喜んで私はプリズムがそれをサポートしているかどうかわかりません、私はもう一度見て、[this](http://www.codeproject.com/KB/WPF/AttachingVirtualBranches.aspx)はそれらの図書館は私が以前に来たが、私は実際にそれを使ったことはないと思うので、このシナリオでうまくいくかどうかわからない。しかし、私はかなり前に[DataContextSpy](http://www.codeproject.com/KB/WPF/ArtificialInheritanceCxt.aspx)と呼ばれる別のものを試しましたが、多分私にはあまり役に立ちませんでした。 ... –

+0

タグのプロパティは、私が行方不明だったものです!ありがとうございました! –