Skip to content

Commit

Permalink
Add extended example of treeview
Browse files Browse the repository at this point in the history
Doesn't fix some bugs, just shows another one =D
Add example of treeview with Add and Remove buttons.
Which also shows that multiactionbutton doesn't adjust PopupBox position
in case of changing it's placement.
  • Loading branch information
l1pton17 committed Dec 13, 2015
1 parent 32be399 commit 00279b3
Show file tree
Hide file tree
Showing 6 changed files with 266 additions and 3 deletions.
21 changes: 21 additions & 0 deletions MainDemo.Wpf/Domain/BindableBase.cs
@@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MaterialDesignColors.WpfExample.Domain
{
public abstract class BindableBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
Volatile.Read(ref PropertyChanged)?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
160 changes: 160 additions & 0 deletions MainDemo.Wpf/Domain/TreesViewModel.cs
@@ -0,0 +1,160 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace MaterialDesignColors.WpfExample.Domain
{
public sealed class Movie : BindableBase
{
private string _name;

public string Name
{
get { return _name; }
set
{
_name = value;
OnPropertyChanged();
}
}

private string _director;

public string Director
{
get { return _director; }
set
{
_director = value;
OnPropertyChanged();
}
}
}

public sealed class MovieCategory : BindableBase
{
public string Name { get; }

public ObservableCollection<Movie> Movies { get; }

public MovieCategory(string name)
{
Name = name;
Movies = new ObservableCollection<Movie>();
}
}

public sealed class TreesViewModel : BindableBase
{
public ObservableCollection<MovieCategory> MovieCategories { get; }

public AnotherCommandImplementation AddCommand { get; }

public AnotherCommandImplementation RemoveSelectedItemCommand { get; }

private object _selectedItem;
public object SelectedItem
{
get { return _selectedItem; }
set
{
_selectedItem = value;
OnPropertyChanged();
}
}

public TreesViewModel()
{
MovieCategories = new ObservableCollection<MovieCategory>
{
new MovieCategory("Action")
{
Movies =
{
new Movie
{
Name = "Predator",
Director = "John McTiernan"
},
new Movie
{
Name = "Alien",
Director = "Ridley Scott"
},
new Movie
{
Name = "Prometheus",
Director = "Ridley Scott"
}
}
},
new MovieCategory("Comedy")
{
Movies =
{
new Movie
{
Name = "EuroTrip",
Director = "Jeff Schaffer"
},
new Movie
{
Name = "EuroTrip",
Director = "Jeff Schaffer"
}
}
}
};

AddCommand = new AnotherCommandImplementation(
_ =>
{
if (!MovieCategories.Any())
{
MovieCategories.Add(new MovieCategory(GenerateString(15)));
}
else
{
int index = new Random().Next(0, MovieCategories.Count);
MovieCategories[index].Movies.Add(
new Movie
{
Name = GenerateString(15),
Director = GenerateString(20)
});
}
});

RemoveSelectedItemCommand = new AnotherCommandImplementation(
_ =>
{
if (SelectedItem is MovieCategory)
{
MovieCategories.Remove(SelectedItem as MovieCategory);
}
else if (SelectedItem is Movie)
{
var movie = SelectedItem as Movie;
MovieCategories.FirstOrDefault(v => v.Movies.Contains(movie))?.Movies.Remove(movie);
}
},
_ => SelectedItem != null);
}

private static string GenerateString(int length)
{
var random = new Random();

return String.Join(String.Empty,
Enumerable.Range(0, length)
.Select(v => (char) random.Next((int)'a', (int)'z' + 1)));
}
}
}
2 changes: 2 additions & 0 deletions MainDemo.Wpf/MainDemo.Wpf.csproj
Expand Up @@ -82,6 +82,7 @@
<DependentUpon>Dialogs.xaml</DependentUpon>
</Compile>
<Compile Include="Domain\AnotherCommandImplementation.cs" />
<Compile Include="Domain\BindableBase.cs" />
<Compile Include="Domain\DemoItem.cs" />
<Compile Include="Domain\DialogsViewModel.cs" />
<Compile Include="Domain\ListFieldsViewModel.cs" />
Expand All @@ -96,6 +97,7 @@
</Compile>
<Compile Include="Domain\SelectableViewModel.cs" />
<Compile Include="Domain\TextFieldsViewModel.cs" />
<Compile Include="Domain\TreesViewModel.cs" />
<Compile Include="Expander.xaml.cs">
<DependentUpon>Expander.xaml</DependentUpon>
</Compile>
Expand Down
6 changes: 5 additions & 1 deletion MainDemo.Wpf/MainWindow.xaml
Expand Up @@ -110,7 +110,11 @@
</domain:DemoItem>
<domain:DemoItem Name="Trees">
<domain:DemoItem.Content>
<wpfExample:Trees />
<wpfExample:Trees>
<wpfExample:Trees.DataContext>
<domain:TreesViewModel/>
</wpfExample:Trees.DataContext>
</wpfExample:Trees>
</domain:DemoItem.Content>
</domain:DemoItem>
<domain:DemoItem Name="Grids">
Expand Down
65 changes: 63 additions & 2 deletions MainDemo.Wpf/Trees.xaml
Expand Up @@ -2,11 +2,25 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:domain="clr-namespace:MaterialDesignColors.WpfExample.Domain"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.PopupBox.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<TreeView HorizontalAlignment="Left" MinWidth="220">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TreeView Grid.Column="0"
MinWidth="220">
<TreeViewItem Header="Fruit">
<TreeViewItem>
<TreeViewItem.Header>
Expand Down Expand Up @@ -74,5 +88,52 @@
</TreeViewItem>
<TreeViewItem Header="Empty" />
</TreeView>
<Grid Grid.Column="1"
MinWidth="220"
VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TreeView Grid.Row="0"
ItemsSource="{Binding MovieCategories}"
MinWidth="220"
SelectedItemChanged="TreeView_SelectedItemChanged">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type domain:MovieCategory}"
ItemsSource="{Binding Movies}">
<TextBlock Text="{Binding Name}" Margin="3 2"/>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type domain:Movie}">
<TextBlock Text="{Binding Name}" Margin="3 2"
ToolTip="{Binding Director}"/>
</DataTemplate>
</TreeView.Resources>
</TreeView>
<materialDesign:PopupBox Grid.Row="1"
Style="{StaticResource MaterialDesignMultiFloatingActionPopupBox}"
PlacementMode="LeftAndAlignTopEdges"
ToolTipService.Placement="Bottom"
ToolTip="Manage items"
Margin="0 0 10 10"
HorizontalAlignment="Right" VerticalAlignment="Bottom">
<StackPanel>
<Button ToolTip="Add an item"
Command="{Binding AddCommand}">
<Path Data="M19,13H13V19H11V13H5V11H11V5H13V11H19V13Z"
Stretch="Uniform"
Width="15" Height="15"
Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"/>
</Button>
<Button ToolTip="Remove selected item"
Command="{Binding RemoveSelectedItemCommand}">
<Path Data="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z"
Stretch="Uniform"
Width="15" Height="15"
Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"/>
</Button>
</StackPanel>
</materialDesign:PopupBox>
</Grid>
</Grid>
</UserControl>
15 changes: 15 additions & 0 deletions MainDemo.Wpf/Trees.xaml.cs
Expand Up @@ -12,6 +12,7 @@
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MaterialDesignColors.WpfExample.Domain;

namespace MaterialDesignColors.WpfExample
{
Expand All @@ -24,5 +25,19 @@ public Trees()
{
InitializeComponent();
}

public TreesViewModel ViewModel => DataContext as TreesViewModel;

/// <summary>
/// TreesView's SelectedItem is read-only. Hence we can't bind it. There is a way to obtain a selected item.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TreeView_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
if (ViewModel == null) return;

ViewModel.SelectedItem = e.NewValue;
}
}
}

0 comments on commit 00279b3

Please sign in to comment.