9

क्या TreeView के HierarchicalDataTemplate में एक अलग ContextMenu का उपयोग करने के लिए कोई आइटम है जो किसी आइटम के डेटा पर निर्भर करता है?डेटा के लिए WPF TreeView में संदर्भ मेनू बदलें

उदाहरण के लिए, प्रदर्शन एक ContextMenu अगर Item.IsFile सच है, एक अलग एक को प्रदर्शित करता है, तो Item.IsFolder सच है, आदि

उत्तर

13

यह ListBox के लिए उदाहरण है, मुझे लगता है कि आप आसानी से इसे TreeView के साथ काम करने को संशोधित कर सकते हैं।

XAML:

... 

<Window.Resources> 
    <ContextMenu x:Key="FileContextMenu"> 
     ... 
    </ContextMenu> 
    <ContextMenu x:Key="DirContextMenu"> 
     ... 
    </ContextMenu> 

    <local:ItemToContextMenuConverter x:Key="ContextMenuConverter" />   
</Window.Resources> 

... 

<ListBox x:Name="SomeList"> 
    <ListBox.ItemTemplate> 
     <DataTemplate>       
      <Label Content="{Binding Path=Name}" ContextMenu="{Binding Converter={StaticResource ContextMenuConverter}}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

कोड:

class Item 
{ 
    public string Name { get; set; } 
    public bool IsFile { get; set; } 
} 

[ValueConversion(typeof(Item), typeof(ContextMenu))] 
public class ItemToContextMenuConverter : IValueConverter 
{ 
    public static ContextMenu FileContextMenu; 
    public static ContextMenu DirContextMenu; 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     Item item = value as Item; 
     if (item == null) return null; 

     return item.IsFile ? FileContextMenu : DirContextMenu; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new Exception("The method or operation is not implemented."); 
    } 
} 

private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     ItemToContextMenuConverter.FileContextMenu 
      = this.Resources["FileContextMenu"] as ContextMenu; 
     ItemToContextMenuConverter.DirContextMenu 
      = this.Resources["DirContextMenu"] as ContextMenu; 

     List<Item> items = new List<Item>(); 
     items.Add(new Item() { Name = "First", IsFile = true }); 
     items.Add(new Item() { Name = "Second", IsFile = false }); 

     SomeList.ItemsSource = items; 
    } 
+0

, पूर्ण उदाहरण के लिए धन्यवाद काफी सही लगता है! – Jared

0

हाय मैं TreeView पर समान बात कर रहा हूँ और मुझे लगता है कि ItemToContextMenuConverter तरह प्रत्येक आइटम भले ही यह नहीं किया जाता है पर निष्पादित किया जाता है नहीं है। यह एक छोटी परियोजना में शायद ठीक है, लेकिन यदि आप प्रत्येक मेनूइटम के लिए सक्षम/अक्षम कोड जोड़ते हैं तो यह धीमा हो सकता है।

यह शायद सबसे अच्छा नहीं है (मैंने अभी WPF के साथ शुरू किया है), लेकिन मैं इसे आपके साथ साझा करूंगा।

मेनू संसाधन:

<Window.Resources> 
    <ContextMenu x:Key="MnuFolderFavorites" StaysOpen="True"> 
    <MenuItem Header="Remove from Favorites" Click="MnuFolder_RemoveFromFavorites_Click"></MenuItem> 
    </ContextMenu> 
    <ContextMenu x:Key="MnuFolder" StaysOpen="True"> 
    <MenuItem Header="New Folder"></MenuItem> 
    <MenuItem Header="Rename" x:Name="MnuFolderRename" Click="MnuFolder_Rename_Click"></MenuItem> 
    <MenuItem Header="Add to Favorites" Click="MnuFolder_AddToFavorites_Click"></MenuItem> 
    </ContextMenu> 
</Window.Resources> 

TreeView:

<TreeView x:Name="TvFolders"> 
    <TreeView.ItemTemplate> 
    <HierarchicalDataTemplate DataType="{x:Type data:Folder}" ItemsSource="{Binding Items}"> 
     <StackPanel Orientation="Horizontal" PreviewMouseRightButtonDown="TvFoldersStackPanel_PreviewMouseRightButtonDown"> 
     <Image Width="20" Height="20" Source="{Binding ImagePath}" /> 
     <TextBlock Text="{Binding Title}" Margin="5,0,0,0" /> 
     </StackPanel> 
    </HierarchicalDataTemplate> 
    </TreeView.ItemTemplate> 
</TreeView> 

कोड:

private void TvFoldersStackPanel_PreviewMouseRightButtonDown(object sender, MouseButtonEventArgs e) { 
    ((StackPanel) sender).ContextMenu = null; 
    Data.Folder item = (Data.Folder) ((StackPanel) sender).DataContext; 
    if (!item.Accessible) return; 
    if (item.Parent != null && item.Parent.Title.Equals("Favorites")) { 
    ((StackPanel) sender).ContextMenu = MainWindow.Resources["MnuFolderFavorites"] as ContextMenu; 
    } else { 
    ((StackPanel) sender).ContextMenu = MainWindow.Resources["MnuFolder"] as ContextMenu; 
    foreach (MenuItem menuItem in ((StackPanel) sender).ContextMenu.Items) { 
     switch (menuItem.Name) { 
     case "MnuFolderRename": { 
      menuItem.IsEnabled = item.Parent != null; 
      break; 
     } 
     } 
    } 
    } 
} 

private void MnuFolder_RemoveFromFavorites_Click(object sender, RoutedEventArgs e) { 
    string path = ((Data.Folder)((MenuItem)sender).DataContext).FullPath; 
    Settings.Default.FolderFavorites.Remove(path); 
    Settings.Default.Save(); 
    FavoritesFolder?.AddFavorites(true); 
} 
संबंधित मुद्दे