I have a tree view which lists the drives & folders in the PC. I am working in MVVM with Micrososft MVVM Toolkit, Fody and Microsoft Behaviors.
I have a Folder Tree view model for PC which creates an Observable Collection of Folder Items represented by a FolderItemViewModel. The simplified test example shown here is started from App.xaml.cs.
I want a context menu similar to File Explorer. I can put a context menu at the tree view items level but I need to change properties in the FolderViewModel which I cannot do from the FolderItemViewModel.
I was hoping Iteractive Triggers would help as it does for Selected Item.
Any assistance will be apreciated.
Xaml:
"""
<TreeView x:Name="tvFolders" Grid.Row="1" Grid.Column="1" ItemsSource="{Binding FolderCollection}"
MinWidth="250" MinHeight="250">
<ie1:Interaction.Triggers >
<ie1:EventTrigger EventName ="SelectedItemChanged" >
<ie1:InvokeCommandAction CommandParameter="{Binding ElementName=tvFolders, Path=SelectedItem}"
Command="{Binding TreeSelectionChangedClick}" />
</ie1:EventTrigger>
</ie1:Interaction.Triggers >
<TreeView.Resources>
<ContextMenu x:Key="TreeViewMenu">
<MenuItem Command="{Binding NewFolderClick}" Header=" New Folder " />
<MenuItem Command="{Binding RenameClick}" Header=" Rename " />
</ContextMenu>
</TreeView.Resources>
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}" >
<Setter Property="ContextMenu" Value="{StaticResource TreeViewMenu}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="True" >
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.ItemTemplate>
<HierarchicalDataTemplate >
<TextBlock Text="{Binding Name}" />
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<StackPanel Orientation="Horizontal" Grid.Row="2" Grid.Column="1" >
<TextBlock Text="Selected Folder: " />
<TextBox Text="{Binding SelectedFolderPath}" />
</StackPanel>
"""
FolderViewModel:
""" internal class FolderTreeViewModel : ObservableObject { public ObservableCollection FolderCollection { get; set; }
public string SelectedFolderPath { get; set; }
public ICommand TreeSelectionChangedClick { get; set; }
public FolderTreeViewModel()
{
List<FolderItemViewModel> FolderItems = new List<FolderItemViewModel>();
// Get the logical drives as a list of DirectoryItemModel
List<FolderItemModel> subFolders = GetLogicalDrives();
foreach (FolderItemModel item in subFolders)
{
FolderItemViewModel folderItemViewModel = new FolderItemViewModel(item.FullPath);
FolderItems.Add(folderItemViewModel);
}
FolderCollection = new ObservableCollection<FolderItemViewModel>(FolderItems);
TreeSelectionChangedClick = new RelayCommand<FolderItemViewModel>(TreeSelectionChangedCommand);
}
public static List<FolderItemModel> GetLogicalDrives()
{
// Get every logical drive on the machine
List<FolderItemModel> DirectoryItems = new List<FolderItemModel>();
string[] drives = Directory.GetLogicalDrives();
foreach (string drive in drives)
{
DirectoryItems.Add(new FolderItemModel { FullPath = drive});
}
return DirectoryItems; // Directory.GetLogicalDrives().Select(drive => new DirectoryItemModel { FullPath = drive, Type = DirectoryItemType.Drive }).ToList();
}
private void TreeSelectionChangedCommand(FolderItemViewModel tVI)
{
if (TreeSelectionChangedClick != null)
{
SelectedFolderPath = tVI.FullPath;
}
}
} """
FolerItemViewModel:
""" namespace TestTreeViewContextMenu.ViewModels { internal class FolderItemViewModel { public string Name { get; set; } public string FullPath { get; set; } public ObservableCollection SubFolders { get; set; }
public ICommand NewFolderClick { get; set; }
public ICommand RenameClick { get; set; }
public FolderItemViewModel(string fullName)
{
FullPath = fullName;
if (fullName == Path.GetPathRoot(fullName))
{
Name = fullName;
}
else
Name = Path.GetFileName(fullName);
SubFolders = new ObservableCollection<FolderItemViewModel>();
NewFolderClick = new RelayCommand(NewFolderCommand);
RenameClick = new RelayCommand(RenameCommand);
}
private void NewFolderCommand()
{
MessageBox.Show("New Folder");
// Cannot update the FolderTreeViewModel ColderCollection from FolderItemViewModel
}
private void RenameCommand()
{
MessageBox.Show($"Rename");
// Cannot update the SelectedFolderPath value from here
}
}
} """