9

TreeViewHierarchicalDataTemplateContextMenu öğesinde, bir öğeye bağlı olan verilere bağlı olarak farklı bir özellik kullanmak için belirtmenin bir yolu var mı? Item.IsFolder doğruysa doğrudur, farklı bir tane görüntülemek biri ContextMenuItem.IsFile ÖrneğinVeri için WPF TreeView içindeki içerik menüsünü değiştir

, ekran vb

cevap

13

Bu ListBox örnektir, sana kolaylıkla TreeView ile çalışmak değiştirebilir düşünüyorum.

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> 

Kodu:

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

, tam örneğin sayesinde hemen hemen mükemmel görünüyor! – Jared

0

Merhaba ben TreeView benzer bir şey yapıyorum ve bu ItemToContextMenuConverter kullanıldığı olmasa bile her öğe üzerinde yürütülür gibi bilmiyorum. Küçük bir projede tamam olabilir, ancak her MenuItem için Enable/Disable (Etkinleştir/Devre Dışı Bırak) kodunu eklerseniz, yavaş olabilir.

Bu belki de en iyisi değil (daha yeni WPF ile başladım), ancak sizinle paylaşacağım.

Menü Kaynaklar:

<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> 

Kodu:

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); 
} 
İlgili konular