2013-02-22 18 views
20

ContextMenu numaralı telefondan doğru DataContext'u nasıl ayarlayacağımı bulmakta sorun yaşıyorum.WPF ContextMenu woes: ContextMenu'nun DataContext özelliğini nasıl ayarlayabilirim?

ItemsControl kaynağının kaynağı olan bir görünüm modelleri koleksiyonum var. Her görünüm modelinde, başka bir ItemsControl kaynağı olan öğelerden oluşan bir koleksiyon bulunur. Her öğe, bir ContextMenu olan resim çizmek için kullanılır. ContextMenu içinde bulunan MenuItems, görünüm modelindeki bir komuta bağlanması gerekir, ancak ContextMenu'un PlacementTarget öğesi tekil öğeye işaret eder.

Benim Xaml şöyle görünür:

<ItemsControl ItemsSource="{Binding Markers"}> 
    <ItemsControl.ItemTemplate> 
     <DataTemplate> 
      <ItemsControl ItemsSource="{Binding Items}"> 
       <ItemsControl.ItemTemplate> 
        <DataTemplate> 
         <Image> 
          <Image.ContextMenu> 
           <ContextMenu> 
            <MenuItem Header="Edit" Command="{Binding EditCommand}" /> 
           </ContextMenu> 
          </Image.ContextMenu> 
         </Image> 
        </DataTemplate> 
       </ItemsControl.ItemTemplate> 
      </ItemsControl> 
     </DataTemplate> 
    </ItemsControl.ItemTemplate> 
</ItemsControl> 

nasıl öğenin karşılık gelen ana görünümü modeline ContextMenu arasında DataContext ayarlayabilirsiniz?

cevap

35

ContextMenu, görsel ağacın dışındadır. Bunun nasıl çalıştığını

<ItemsControl ItemsSource="{Binding Markers}" Tag="{Binding ElementName=outerControl, Path=DataContext}"> 
    ... 
    <ContextMenu DataContext="{Binding Path=PlacementTarget.Tag, RelativeSource={RelativeSource Self}}"> 
     <MenuItem Header="Edit" 
       Command="{Binding EditCommand}" /> 
    </ContextMenu> 
    ... 
</ItemsControl> 

Bu post açıklıyor: Aşağıda size datacontext almalısınız xaml olduğunu. Bu yapalım

using System; 
using System.Windows.Controls; 
using System.Windows.Markup; 
using System.Xaml; 

[MarkupExtensionReturnType(typeof(ContentControl))] 
public class RootObject : MarkupExtension 
{ 
    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     var rootObjectProvider = (IRootObjectProvider)serviceProvider.GetService(typeof(IRootObjectProvider)); 
     return rootObjectProvider?.RootObject; 
    } 
} 

:

<ItemsControl ItemsSource="{Binding Markers}"> 
    ... 
    <ContextMenu DataContext="{Binding DataContext, Source={local:RootObject}}"> 
     <MenuItem Header="Edit" 
       Command="{Binding EditCommand}" /> 
    </ContextMenu> 
    ... 
</ItemsControl> 
+1

bu ben PlacementTarget olana bağlamak istemiyorum sorun. Dış kontrolün DataContext'ine bağlamak istiyorum. –

+0

Aynı DataContext'in (örn. OuterControl ve iç öğelerControl) bulunmadığından emin misiniz? – kevindaub

+0

Evet, PlacementTarget kullanıyorum DataContext çok derin bir düzeydir. Bir öğeyi geri alıyorum, ancak ihtiyacım olan şey, bu öğeyi içeren koleksiyona sahip görünüm modelidir. Dış kontrolün DataContext'ine bağlanabilirsem, bu mükemmel olurdu. –

8

Bir markupextension kullanabilirsiniz. Ekli mülkü tercih ederim.

public static readonly DependencyProperty DataContextExProperty = DependencyProperty.RegisterAttached("DataContextEx", typeof(Object), typeof(DependencyObjectAttached)); 

    public static Object GetDataContextEx(DependencyObject element) 
    { 
     return element.GetValue(DataContextExProperty); 
    } 

    public static void SetDataContextEx(DependencyObject element, Object value) 
    { 
     element.SetValue(DataContextExProperty, value); 
    } 

XAML olarak:

Sen ekli özellik eklemek gerek

<Button attached:DependencyObjectAttached.DataContextEx="{Binding ElementName=MyDataContextElement, Path=DataContext}"> 
     <Button.ContextMenu> 
      <ContextMenu DataContext="{Binding RelativeSource={RelativeSource Self}, Path=PlacementTarget.(attached:DependencyObjectAttached.DataContextEx)}"> 

      </ContextMenu> 
     </Button.ContextMenu> 
    </Button> 
+1

Ah Evet, Cuma, saat 4:00 ve bu işe yarıyor! – grunge

2

Ben kullanım Etiket sevmiyorum

İlgili konular