2017-04-17 6 views
1

Ich habe ein Benutzersteuerelement (namens mUserControl) mit einigen Textfeldern, deren Inhalt an Eigenschaften einer Klasse (Modell) namens Module gebunden ist. Das Benutzersteuerelement selbst verfügt über eine benutzerdefinierte Abhängigkeitseigenschaft (ItemSource) des Typs Module. So kann ich den Inhalt von Textfeldern an Eigenschaften des Moduls binden.WPF ContextMenu nicht Abhängigkeitseigenschaft des Benutzersteuerelements

Dieses Benutzersteuerelement ist Teil einer größeren Ansicht (HomeScreenView). Ich bekomme leicht Zugriff auf ItemsSource von HomeScreenViewmodel. Alles funktioniert gut außer einem ContextMenu in Textfeldern. Ich bekomme einen verbindlichen Fehler. ContextMenu zeigt die ItemsSource-Eigenschaft des Benutzersteuerelements nicht an, während alle anderen Elemente dies tun. Ich weiß, ContextMenu ist auf verschiedenen visuellen Baum. Ich habe verschiedene Wege ausprobiert, um diese Arbeit zu bekommen, ohne Erfolg. Irgendwelche Vorschläge sind willkommen!

Benutzersteuerelement XAML (aus Gründen der Klarheit vereinfacht):

<UserControl x:Class="xxx.Views.ModuleFrameView" 
x:Name="mUserControl"> 
<Grid> 
<TextBox x:Name="txt5" Text="{Binding ItemSource.Ch1SET, 
ElementName=mUserControl}" IsEnabled="{Binding ItemSource.IsEnbl_5, 
ElementName=mUserControl}" IsReadOnly="True"       
TextAlignment="Center" ContextMenuService.ShowOnDisabled="True" 
Tag="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}"> 
<TextBox.ContextMenu > 
    <ContextMenu Name="cm"> 
      <MenuItem Header="Enable" cal:Message.Attach="cmEnable($source)" IsCheckable="True" IsChecked=" 
{Binding Path=PlacementTarget.Tag.DataContext.ItemSource.IsEnbl_5, 
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TextBox}}"/> 
    </ContextMenu> 
</TextBox.ContextMenu> 
<!--...--> 

ModuleFrameView hat eine ItemSource Eigenschaft in definierten Code-behind-Datei:

public Module ItemSource 
    { 
     get { return (Module)GetValue(ItemSourceProperty); } 
     set { SetValue(ItemSourceProperty, value); } 
    } 

    public static readonly DependencyProperty ItemSourceProperty = 
    DependencyProperty.Register("ItemSource", typeof(Module), typeof(ModuleFrameView), new PropertyMetadata(default(Module))); 

Dieser DP vom Typ Modul:

public class Module : PropertyChangedBase 
{ 
    private string _ch1SET; 
    public string Ch1SET 
    { 
     get { return _ch1SET; } 
     set 
     { 
      if (_ch1SET == value) return; 
      _ch1SET = value; 
      NotifyOfPropertyChange(() => Ch1SET); 
     } 
    } 
private bool _isEnbl_5; 
    public bool IsEnbl_5 
    { 
     get { return _isEnbl_5; } 
     set 
     { 
      if (_isEnbl_5 == value) return; 
      _isEnbl_5 = value; 
      NotifyOfPropertyChange(() => IsEnbl_5); 
     } 
    } 
//... 
//...lot of properties 

Zweite Benutzerkontrolle (oben erwähnte größere Ansicht) xaml:

012 + „ItemSource“
<UserControl x:Class="xxx.Views.HomeScreenView"> 
<Grid> 
    <ContentControl> 
<loc:ModuleFrameView Grid.Row="0" Grid.Column="0" ItemSource="{Binding ModuleArr[0]}"/> 
<loc:ModuleFrameView Grid.Row="0" Grid.Column="1" ItemSource="{Binding ModuleArr[1]}"/> 
<!--...--> 

Antwort

0

ein bisschen latte, aber wenn Ihr Datacontext richtig eingestellt ist, müssen Sie keine Namen und Sie können wie unten (nicht getestet) vereinfachen, sondern ein DP zugegriffen werden kann direkt falsch Eigenschaftsnamen, wenn Sie nur ein Element haben => Änderung „CurrentModule“

<UserControl x:Class="xxx.Views.ModuleFrameView"> 
    <Grid x:Name="ROOT"> 
     <TextBox Text="{Binding CurrentModule.Ch1SET}" IsEnabled="{Binding CurrentModule.IsEnbl_5}" IsReadOnly="True"       
TextAlignment="Center" ContextMenuService.ShowOnDisabled="True"> 
<TextBox.ContextMenu > 
    <ContextMenu> 
     <MenuItem Header="Enable" cal:Message.Attach="cmEnable($source)" IsCheckable="True" IsChecked="{Binding Path=CurrentModule.IsEnbl_5, ElementName="ROOT"}"/> 
    </ContextMenu> 
</TextBox.ContextMenu> 

daneben, Ihre HomeScreenView, müssen durch eine Liste Sammlung von Modul binded ersetzt werden, und ein Element Vorlage Ihrer loc definieren: ModuleFrameView mit " List ItemSource = "{Binding ModuleArr}"

0

PlacementTarget ist eine Eigenschaft

<MenuItem Header="Enable" cal:Message.Attach="cmEnable($source)" IsCheckable="True" 
      IsChecked="{Binding Path=PlacementTarget.Tag.DataContext.ItemSource.IsEnbl_5, 
      RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/> 
: die Mutter ContextMenu so sollten Sie ContextMenu als AncestorType statt TextBox verwenden
Verwandte Themen