2011-07-26 35 views
5

Bir ContextMenu'nun içindeki UserControl'ün orijinal DataContextini nasıl edinebilirim.Erişim GörünümüModel/DataConext ContextMenu içinde

Aşağıdaki kodda, DataTemplate'de doğru bağlanan bir Düğme olduğunu görebilirsiniz.

System.Windows.Data Hata: 4: contextmenu ait veri kaynağı bağlamak için çalışıyor Ancak, ben ararken aşağıdaki hata atfen 'RelativeSource FindAncestor, AncestorType =' System.Windows bağlama için kaynak bulunamıyor. Controls.TreeView ', AncestorLevel =' 1 ''. BindingExpression: Yol = DataContext; Dataıtem = null; hedef eleman 'ContextMenu' (Name = ''); hedef özellik 'DataContext' ('Object') 'dir

ContextMenu'nun ViewModel'e bağlanmasına izin vermek için ne yapmam gerekir?

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

ViewModel, codebehind'deki görünümün veri dosyasına atanır. :

Görünüm:

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

cevap

9

ContextMenus, RelativeSource-bindings'in başarısız olmasına neden olan görsel ağaçta görünmüyor, yine de DataContext'u bir şekilde veya başka şekilde alabilirsiniz.

<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 ve DataContext Tag aracılığıyla tünellenir: Örneğin bu deneyebilirsiniz. Bunu yapmanın bir yolu (en azından umarım işe yarıyor), ayrıca bu boşluğu farklı bir şekilde köprüleyen bazı kütüphaneler görmüştüm ama onların menşeini hatırlamıyorum ...

+0

Bu işe yaradı! Teşekkür ederim! Bu boşluğu kaldırabilecek diğer kütüphanelerden bahsettin, Prizma bunlardan biri mi? –

+0

Yardım ettiğine sevindim :) Prism'in bunun için bir desteği olup olmadığını bilmiyorum, sadece tekrar etrafa baktım ve [bu] (http://www.codeproject.com/KB/WPF/AttachingVirtualBranches.aspx) Bu kütüphaneleri daha önce rastladım ama aslında hiç kullanmadığımı düşündüğümden bu senaryoda çalışıp çalışmayacağını bilmiyorum. Ben ancak bir süre önce [DataContextSpy] (http://www.codeproject.com/KB/WPF/ArtificialInheritanceCxt.aspx) denilen başka bir şey denedim ama bana çok fazla kullanmadı, belki yanlış uyguladı. ... –

+0

Tag özelliği eksik olan şeydir! Teşekkür ederim! –