2011-07-29 37 views
0

而且我有一個TreeView一個用戶控件,並用文本菜單的DependencyProperty:如何將ContextMenu綁定到每個TreeView項目?

public ObservableCollection<Control> ContextMenu { 
     get { 
      return (ObservableCollection<Control>)GetValue(ContextMenuProperty); 
     } 
     set { 
      SetValue(ContextMenuProperty, value); 
     } 
    } 

    public static readonly DependencyProperty ContextMenuProperty = 
     DependencyProperty.Register("ContextMenu", typeof(ObservableCollection<Control>), typeof(FilterableTreeViewControl), 
     new PropertyMetadata(new ObservableCollection<Control>(), new PropertyChangedCallback(FilterableTreeViewControl.OnContextMenuPropertyChange))); 

    private static void OnContextMenuPropertyChange(DependencyObject d, DependencyPropertyChangedEventArgs e) { 
     FilterableTreeViewControl ctrl = d as FilterableTreeViewControl; 
     ctrl.OnContextMenuChange((Object)e.NewValue); 
    } 

    protected virtual void OnContextMenuChange(Object NewItemsSource) { 
    } 

的XAML:

 <controlsToolkit:TreeViewDragDropTarget AllowDrop="True" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" Drop="TreeViewDragDropTarget_Drop" AllowedSourceEffects="All"> 
      <controlsToolkit:TreeViewDragDropTarget.Resources> 
       <Data:HierarchicalDataTemplate x:Key="TreeViewTemplate" ItemsSource="{Binding Children}"> 
        <StackPanel Orientation="Horizontal" Height="Auto" Width="Auto"> 
         <Image Source="{Binding Type,Converter={StaticResource TreeIconConverter}}" /> 
         <TextBlock x:Name="NameTextBlock" Text="{Binding Name}"> 
          <controlsInputToolkit:ContextMenuService.ContextMenu> 
           <controlsInputToolkit:ContextMenu ItemsSource="{Binding ElementName=MyTreeViewControl, Path=ContextMenu}" /> 
          </controlsInputToolkit:ContextMenuService.ContextMenu> 
         </TextBlock> 
        </StackPanel> 
       </Data:HierarchicalDataTemplate> 
      </controlsToolkit:TreeViewDragDropTarget.Resources> 
      <Controls:TreeView Name="treeView" ItemTemplate="{StaticResource TreeViewTemplate}"> 
      </Controls:TreeView> 
     </controlsToolkit:TreeViewDragDropTarget> 

用法:

 <my:MyControl 
       DragEnabled="False" 
       ItemsSource="{Binding TreeRootNodes}" 
       FilterCaption="Filter:" 
       SelectionChangedCommand="{Binding SelectedMachineGroupChangedCommand_L}" 
       DropCommand="{Binding DropCommand}"> 
      <my:FilterableTreeViewControl.ContextMenu> 
       <controlsInputToolkit:MenuItem Header="Menu 1" /> 
       <controlsInputToolkit:MenuItem Header="Menu 2" /> 
       <controlsInputToolkit:MenuItem Header="Menu 3" /> 
      </my:MyControl.ContextMenu> 
     </my:MyControl> 

第一工作一切正常,但在第二次之後,我明顯得到了「元素已經是另一個元素的孩子」。例外。

是否可以通過綁定來解決這個問題,而沒有任何代碼隱藏?

回答

1

你會得到「元素已經是另一個元素的孩子」。異常,因爲您的TreeView中的所有項都將其ContextMenus綁定到相同的對象(您在其中定義的ContextMenu)。

反而暴露出的ContextMenu作爲MyControl屬性可以公開其HeirarchicalDataTemplate代替:

public HeirarchicalDataTemplate TreeViewItemTemplate { 
    get { 
     return (HeirarchicalDataTemplate)this.treeView.ItemTemplate; 
    } 
    set { 
     this.treeView.ItemTemplate = value; 
    } 
} 

如果你選擇走這條路,你必須確定你原來的用戶控制之外的TreeView控件的ItemTemplate。在使用用戶控件外部客戶端,你可以這樣做:

<my:MyControl> 
     <my:MyControl.TreeViewItemTemplate> 
      <Data:HierarchicalDataTemplate> 
        <!-- Rest of the template --> 
        <TextBlock x:Name="NameTextBlock" Text="{Binding Name}"> 
         <controlsInputToolkit:ContextMenuService.ContextMenu> 
          <!-- ContextMenu --> 
         </controlsInputToolkit:ContextMenuService.ContextMenu> 
        <!-- Rest of the template --> 
      </Data:HierarchicalDataTemplate> 
     </my:MyControl.TreeViewItemTemplate> 
    </my:MyControl> 

做它像這樣也增加了你的用戶控件的副作用的靈活性,因爲您現在可以在來自外部的用戶控件自定義TreeView控件的ItemTemplate。如果要一致地重用它,可以將HierarchicalDataTemplate放在ResourceDictionary中。


第二個解決辦法,如果你願意使用的代碼背後,是隻使用一個文本菜單整個用戶控件,然後編程方式確定的代碼被選定爲後面的客戶端,它的項目。

<my:MyControl> 
     <my:MyControl.TreeViewItemTemplate> 
      <controlsInputToolkit:ContextMenuService.ContextMenu> 
       <!-- ContextMenu --> 
      </controlsInputToolkit:ContextMenuService.ContextMenu> 
     </my:MyControl.TreeViewItemTemplate> 
    </my:MyControl> 
+0

非常好的主意,謝謝! – Aaaaaaaa

+0

它可以工作,但我無法將命令綁定到MenuItems:'' - 不起作用。如果我更改ElementName,我不會得到任何綁定異常。任何想法? – Aaaaaaaa

+0

它給你什麼例外?您是在「MyMainPage」還是ResourceDictionary中定義此綁定? – fsong

相關問題