Using the MVVM pattern, I am trying to build a TreeView in XAML that looks like this (Note that bracketed items are actually representative of buttons):
- [Edit] [Delete] Location 1
- [Edit] [Delete] Location 1, Project 1
- [Edit] [Delete] Location 1, Project 2
- [Edit] [Delete] Location 1, Project 3
- [New Project]
- [Edit] [Delete] Location 2
- [Edit] [Delete] Location 2, Project 1
- [New Project]
- [Edit] [Delete] Location 3
- [Edit] [Delete] Location 3, Project 1
- [Edit] [Delete] Location 3, Project 2
- [New Project]
- [New Location]
The idea is that each node in the TreeView has two buttons next to the header text that a user can click to delete/edit the node. Then, at the bottom of each "group" of projects, there is a [New Project] button that can be clicked to add a new project to that "group". Finally, there is a [New Location] button at the bottom of the entire TreeView so that a new Location node can be added.
I have the TreeView and the [New Location] button laid out correctly, but can't figure out how to add the [New Project] button to the bottom of the group of projects for each Location. I've tried using multiple nested TreeView controls, but then the grouping and scrolling don't seem to function as expected.
Here is my MainPageView code:
<UserControl xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightApplication2.MainPageView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:silverlightApplication2="clr-namespace:SilverlightApplication2"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">
<UserControl.DataContext>
<silverlightApplication2:MainPageViewModel/>
</UserControl.DataContext>
<StackPanel Orientation="Vertical">
<sdk:TreeView ItemsSource="{Binding Locations}" BorderBrush="Transparent">
<sdk:TreeView.ItemTemplate>
<sdk:HierarchicalDataTemplate ItemsSource="{Binding Projects}">
<StackPanel Orientation="Horizontal">
<Button Margin="2">
<Image Source="edit.png"/>
<ToolTipService.ToolTip>
<ToolTip Content="Edit item"/>
</ToolTipService.ToolTip>
</Button>
<Button Margin="2">
<Image Source="delete.png"/>
<ToolTipService.ToolTip>
<ToolTip Content="Delete item"/>
</ToolTipService.ToolTip>
</Button>
<sdk:TreeViewItem Header="{Binding Name}"/>
</StackPanel>
</sdk:HierarchicalDataTemplate>
</sdk:TreeView.ItemTemplate>
</sdk:TreeView>
<Button Margin="30,0,0,0" Height="23" Width="23" HorizontalAlignment="Left">
<Image Source="green-plus-sign-md.png"></Image>
<ToolTipService.ToolTip>
<ToolTip Content="Add new location"/>
</ToolTipService.ToolTip>
</Button>
</StackPanel>
</UserControl>
Here is my MainPageViewModel code:
using System.Collections.ObjectModel;
namespace SilverlightApplication2
{
public class MainPageViewModel
{
#region Constructors
public MainPageViewModel()
{
this.Locations = new ObservableCollection<LocationViewModel>
{
new LocationViewModel
{
Name = "Location 1",
Projects = new ObservableCollection<ProjectViewModel>
{
new ProjectViewModel { Name = "Location 1 - Project 1"},
new ProjectViewModel { Name = "Location 1 - Project 2"},
new ProjectViewModel { Name = "Location 1 - Project 3"},
new ProjectViewModel { Name = "Location 1 - Project 4"},
}
},
new LocationViewModel
{
Name = "Location 2",
Projects = new ObservableCollection<ProjectViewModel>
{
new ProjectViewModel { Name = "Location 2 - Project 1"},
new ProjectViewModel { Name = "Location 2 - Project 2"}
}
},
new LocationViewModel
{
Name = "Location 3",
Projects = new ObservableCollection<ProjectViewModel>
{
new ProjectViewModel { Name = "Location 3 - Project 1"},
new ProjectViewModel { Name = "Location 3 - Project 2"},
new ProjectViewModel { Name = "Location 3 - Project 3"},
new ProjectViewModel { Name = "Location 3 - Project 4"},
new ProjectViewModel { Name = "Location 3 - Project 5"},
new ProjectViewModel { Name = "Location 3 - Project 6"},
new ProjectViewModel { Name = "Location 3 - Project 7"}
}
}
};
}
#endregion
#region Properties
public ObservableCollection<LocationViewModel> Locations { get; set; }
#endregion
}
}
Here is the LocationViewModelCode:
using System.Collections.ObjectModel;
using Microsoft.Practices.Prism.ViewModel;
namespace SilverlightApplication2
{
public class LocationViewModel : NotificationObject
{
#region Properties
public string Name { get; set; }
public ObservableCollection<ProjectViewModel> Projects { get; set; }
#endregion
}
}
And finally, the ProjectViewModel code:
namespace SilverlightApplication2
{
public class ProjectViewModel
{
#region Properties
public string Name { get; set; }
#endregion
}
}
As you can see, I am doing this in Silverlight, but a WPF solution would probably be just as good if somebody knows how to do that.
I also realize that this can probably be done pretty easily with code-behind, but I am trying to stay true to the MVVM pattern and find a way to do this purely in XAML.
Thanks for any help.