2016-04-01 15 views
1

Ich habe eine Baumansicht mit einer Dropdown-Schaltfläche. Die Dropdown-Schaltfläche zeigt Optionen zum Hinzufügen von Knoten zum Baum an. Wenn der Benutzer eine Option auswählt, möchte ich, dass ein Befehl abgefeuert und von einem Befehl im übergeordneten Benutzersteuerelement verarbeitet wird. FYI mit catel MVVM-Framework.WPF-Bindung funktioniert nicht bei verschachtelter Listenansicht

XAML

<Grid Margin="10"> 
    <TreeView x:Name="CriteriaTreeView" ItemsSource="{Binding Criteria}"> 
    <i:Interaction.Triggers> 
     <i:EventTrigger EventName="SelectedItemChanged"> 
     <catel:EventToCommand Command="{Binding NodeSelectionChanged}" CommandParameter="{Binding ElementName=CriteriaTreeView, Path=SelectedItem}" DisableAssociatedObjectOnCannotExecute="False" /> 
     </i:EventTrigger> 
    </i:Interaction.Triggers> 
    <TreeView.Resources> 
     <HierarchicalDataTemplate DataType="{x:Type self:Group}" ItemsSource="{Binding Items}"> 
     <StackPanel Orientation="Horizontal"> 
      <ComboBox ItemsSource="{Binding OperatorOptions}" SelectedValue="{Binding SelectedOperator}" DisplayMemberPath="DisplayText" SelectedValuePath="Value" /> 
     </StackPanel> 
     </HierarchicalDataTemplate> 
     <DataTemplate DataType="{x:Type self:Leaf}"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBlock Text="Where Account Number " /> 
      <ComboBox ItemsSource="{Binding OperatorOptions}" SelectedValue="{Binding SelectedOperator}" DisplayMemberPath="DisplayText" SelectedValuePath="Value" /> 
      <TextBox Text="{Binding Value}" Width="50" /> 
     </StackPanel> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type self:NodeFactory}"> 
     <xctk:DropDownButton Content="Add Condition" IsOpen="{Binding IsOpen}"> 
      <xctk:DropDownButton.DropDownContent> 
      <ListView ItemsSource="{Binding AddOptions}" SelectedValue="{Binding SelectedOption}"> 
       <i:Interaction.Triggers> 
       <i:EventTrigger EventName="PreviewMouseLeftButtonDown"> 
        <catel:EventToCommand Command="{Binding Source={x:Reference ManageSyncControl}, Path=DataContext.AddNode}" DisableAssociatedObjectOnCannotExecute="False" /> 
       </i:EventTrigger> 
       </i:Interaction.Triggers> 
       <ListView.ItemTemplate> 
       <DataTemplate> 
        <WrapPanel> 
        <TextBlock Text="{Binding DisplayText}" /> 
        </WrapPanel> 
       </DataTemplate> 
       </ListView.ItemTemplate> 
      </ListView> 
      </xctk:DropDownButton.DropDownContent> 
     </xctk:DropDownButton> 
     </DataTemplate> 
    </TreeView.Resources> 
    </TreeView> 
</Grid> 

Ansichtsmodell

public class ManageSyncedAccountsViewModel: ViewModelEventBase { 
 
     public ManageSyncedAccountsViewModel(IEventAggregator eventAggregator): base(eventAggregator) { 
 
     AddNode = new Command(OnAddNode); 
 
     NodeSelectionChanged = new Command <Node> (OnNodeSelectionChanged); 
 

 
     var root = new Group("Root"); 
 
     var g1 = new Group("Group 1"); 
 
     g1.AddNode(new Leaf("Leaf 1")); 
 
     g1.AddNode(new Leaf("Leaf 2")); 
 
     var g2 = new Group("Group2"); 
 
     g2.AddNode(new Leaf("Leaf 3")); 
 
     g2.AddNode(new Leaf("Leaf 4")); 
 
     root.AddNode(g1); 
 
     root.AddNode(g2); 
 
     root.AddNode(new Leaf("Leaf 5")); 
 

 
     Criteria = new List <Group> { 
 
      root 
 
     }; 
 
     } 
 

 
     private void OnNodeSelectionChanged(Node target) { 
 
     SelectedNode = target; 
 
     } 
 

 
     private void OnAddNode() { 
 
     Console.Out.WriteLine("WOOHOO"); 
 
     } 
 

 
     public List <Group> Criteria { 
 
     get { 
 
      return GetValue < List <Group>> (CriteriaProperty); 
 
     } 
 
     set { 
 
      SetValue(CriteriaProperty, value); 
 
     } 
 
     } 
 

 
     public static readonly PropertyData CriteriaProperty = RegisterProperty(nameof(Criteria), typeof(List <Group>)); 
 

 

 
     public Node SelectedNode { 
 
     get { 
 
      return GetValue <Node> (SelectedNodeProperty); 
 
     } 
 
     set { 
 
      SetValue(SelectedNodeProperty, value); 
 
     } 
 
     } 
 

 
     public static readonly PropertyData SelectedNodeProperty = RegisterProperty(nameof(SelectedNode), typeof(Node)); 
 

 
     public Command AddNode { 
 
     get; 
 
     private set; 
 
     } 
 
     public Command <Node> NodeSelectionChanged { 
 
     get; 
 
     private set; 
 
     } 
 
    }

Als ich betreiben diese ich einen verbindlichen Fehler:

System.Windows.Data Error: 40 : BindingExpression path error: 'AddNode' property not found on 'object' ''MainWindowViewModel' (HashCode=-1718218621)'. BindingExpression:Path=DataContext.AddNode; DataItem='ManageSyncedAccountsView' (Name='ManageSyncControl'); target element is 'EventToCommand' (HashCode=6678752); target property is 'Command' (type 'ICommand')

Ich habe versucht, mit relativer Quelle nach Vorläufertyp und Elementnamen zu suchen, aber beide Optionen haben noch verwirrendere Fehlermeldungen zurückgegeben. Offensichtlich vermisse ich hier etwas.

Danke.

Antwort

2

Laut der Fehlermeldung in Ihrer Frage ist der DataContext des Buttons vom Typ MainWindowViewModel, aber die Klasse, die den AddNode Befehl besitzt, heißt ManageSyncedAccountsViewModel. Versuchen

System.Windows.Data Error: 40 : BindingExpression path error: 'AddNode' property not found on 'object' ''MainWindowViewModel' (HashCode=-1718218621)'. BindingExpression:Path=DataContext.AddNode; DataItem='ManageSyncedAccountsView' (Name='ManageSyncControl'); target element is 'EventToCommand' (HashCode=6678752); target property is 'Command' (type 'ICommand')

AddNode auf MainWindowViewModel setzen, wo die Taste, um es zu sehen.

+1

Und das Problem "zu lange auf das Problem starren und nicht sorgfältig lesen" schlägt wieder. Vielen Dank Ed, Gehirn saß fest und ignorierte den Teil in Fettschrift! – Bitfiddler

+0

@BitFiddler Prost! –

Verwandte Themen