Skip to content

Commit 4ea5efd

Browse files
committed
first cut of API for displaying tree node content outside of ripple #896
1 parent 019c5d6 commit 4ea5efd

File tree

5 files changed

+178
-2
lines changed

5 files changed

+178
-2
lines changed

MainDemo.Wpf/Domain/TreesViewModel.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using MaterialDesignThemes.Wpf;
2+
using System;
23
using System.Collections.Generic;
34
using System.Collections.ObjectModel;
45
using System.ComponentModel;
@@ -7,9 +8,24 @@
78
using System.Text;
89
using System.Threading;
910
using System.Threading.Tasks;
11+
using System.Windows;
12+
using System.Windows.Controls;
1013

1114
namespace MaterialDesignColors.WpfExample.Domain
1215
{
16+
public class TreeExampleSimpleTemplateSelector : DataTemplateSelector
17+
{
18+
public DataTemplate SolarSystemTemplate { get; set; }
19+
20+
public override DataTemplate SelectTemplate(object item, DependencyObject container)
21+
{
22+
if (item?.ToString() == "Solar System")
23+
return SolarSystemTemplate;
24+
25+
return TreeViewAssist.SuppressAdditionalTemplate;
26+
}
27+
}
28+
1329
public sealed class Movie
1430
{
1531
public Movie(string name, string director)

MainDemo.Wpf/Trees.xaml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@
2020
<ColumnDefinition Width="Auto"/>
2121
<ColumnDefinition Width="Auto"/>
2222
</Grid.ColumnDefinitions>
23+
<Grid.RowDefinitions>
24+
<RowDefinition Height="Auto" />
25+
<RowDefinition Height="Auto" />
26+
</Grid.RowDefinitions>
2327
<smtx:XamlDisplay Key="trees_1" Grid.Column="0" Margin="5 5 0 5" VerticalContentAlignment="Top">
2428
<TreeView MinWidth="220">
2529
<TreeViewItem Header="Fruit">
@@ -137,6 +141,36 @@
137141
</materialDesign:PopupBox>
138142
</Grid>
139143
</smtx:XamlDisplay>
144+
<smtx:XamlDisplay Key="trees_3" Grid.Row="1">
145+
<TreeView>
146+
<materialDesign:TreeViewAssist.AdditionalTemplate>
147+
<DataTemplate>
148+
<TextBlock FontSize="10" Margin="8">8 planets</TextBlock>
149+
</DataTemplate>
150+
</materialDesign:TreeViewAssist.AdditionalTemplate>
151+
<!--
152+
<materialDesign:TreeViewAssist.AdditionalTemplateSelector>
153+
<domain:TreeExampleSimpleTemplateSelector>
154+
<domain:TreeExampleSimpleTemplateSelector.SolarSystemTemplate>
155+
<DataTemplate>
156+
<TextBlock>8 or 9 planets?</TextBlock>
157+
</DataTemplate>
158+
</domain:TreeExampleSimpleTemplateSelector.SolarSystemTemplate>
159+
</domain:TreeExampleSimpleTemplateSelector>
160+
</materialDesign:TreeViewAssist.AdditionalTemplateSelector>
161+
-->
162+
<TreeViewItem Header="Solar System">
163+
<TreeViewItem Header="Mercury" materialDesign:TreeViewAssist.AdditionalTemplate="{x:Static materialDesign:TreeViewAssist.SuppressAdditionalTemplate}" />
164+
<TreeViewItem Header="Venus" />
165+
<TreeViewItem Header="Earth" />
166+
<TreeViewItem Header="Mars" />
167+
<TreeViewItem Header="Jupiter" />
168+
<TreeViewItem Header="Saturn" />
169+
<TreeViewItem Header="Uranus" />
170+
<TreeViewItem Header="Neptune" />
171+
</TreeViewItem>
172+
</TreeView>
173+
</smtx:XamlDisplay>
140174
</Grid>
141175
</UserControl>
142176

MaterialDesignThemes.Wpf/MaterialDesignThemes.Wpf.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -394,6 +394,7 @@
394394
<Compile Include="Transitions\TransitioningContent.cs" />
395395
<Compile Include="Transitions\TransitioningContentBase.cs" />
396396
<Compile Include="TreeHelper.cs" />
397+
<Compile Include="TreeViewAssist.cs" />
397398
<Compile Include="Underline.cs" />
398399
<Compile Include="ValidationAssist.cs" />
399400
<EmbeddedResource Include="Properties\Resources.resx">

MaterialDesignThemes.Wpf/Themes/MaterialDesignTheme.TreeView.xaml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
</ResourceDictionary>
1212
</ResourceDictionary.MergedDictionaries>
1313

14+
<converters:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter" />
15+
1416
<Style x:Key="MaterialDesignTreeView" TargetType="{x:Type TreeView}">
1517
<Setter Property="Background" Value="Transparent"/>
1618
<Setter Property="BorderBrush" Value="{x:Null}"/>
@@ -170,6 +172,7 @@
170172
<ColumnDefinition Width="*"/>
171173
</Grid.ColumnDefinitions>
172174
<Grid.RowDefinitions>
175+
<RowDefinition Height="Auto"/>
173176
<RowDefinition Height="Auto"/>
174177
<RowDefinition/>
175178
</Grid.RowDefinitions>
@@ -284,7 +287,15 @@
284287
</wpf:Ripple>
285288
</Grid>
286289

287-
<StackPanel Grid.Column="1" Grid.Row="1"
290+
<ContentControl Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"
291+
x:Name="AdditionalContentControl"
292+
Content="{TemplateBinding Header}"
293+
ContentTemplate="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:TreeViewAssist.AdditionalTemplate)}"
294+
ContentTemplateSelector="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:TreeViewAssist.AdditionalTemplateSelector)}"
295+
Visibility="Collapsed">
296+
</ContentControl>
297+
298+
<StackPanel Grid.Column="1" Grid.Row="2"
288299
x:Name="ItemsPanel"
289300
Margin="-16 0 0 0"
290301
Grid.ColumnSpan="2">
@@ -301,6 +312,14 @@
301312
</StackPanel>
302313
</Grid>
303314
<ControlTemplate.Triggers>
315+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:TreeViewAssist.AdditionalTemplate), Converter={StaticResource NullableToVisibilityConverter}, Mode=OneWay}"
316+
Value="Visible">
317+
<Setter TargetName="AdditionalContentControl" Property="Visibility" Value="Visible" />
318+
</DataTrigger>
319+
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=(wpf:TreeViewAssist.AdditionalTemplateSelector), Converter={StaticResource NullableToVisibilityConverter}, Mode=OneWay}"
320+
Value="Visible">
321+
<Setter TargetName="AdditionalContentControl" Property="Visibility" Value="Visible" />
322+
</DataTrigger>
304323
<Trigger Property="HasItems" Value="false">
305324
<Setter Property="Visibility" TargetName="Expander" Value="Hidden"/>
306325
</Trigger>
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using System.Text;
6+
using System.Threading.Tasks;
7+
using System.Windows;
8+
using System.Windows.Controls;
9+
using System.Windows.Markup;
10+
11+
namespace MaterialDesignThemes.Wpf
12+
{
13+
public static class TreeViewAssist
14+
{
15+
/// <summary>
16+
/// Allows additional rendering for each tree node, outside of the rippled part of the node which responsds to user selection.
17+
/// </summary>
18+
/// <remarks>
19+
/// The content to be rendered is the same of the <see cref="TreeViewItem"/>; i.e the Header property, or
20+
/// some other content such as a view model, typically when using a <see cref="HierarchicalDataTemplate"/>.
21+
/// </remarks>
22+
public static readonly DependencyProperty AdditionalTemplateProperty = DependencyProperty.RegisterAttached(
23+
"AdditionalTemplate",
24+
typeof(DataTemplate),
25+
typeof(TreeViewAssist),
26+
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
27+
28+
/// <summary>
29+
/// Sets the additional template.
30+
/// </summary>
31+
/// <param name="element">The element.</param>
32+
/// <param name="value">The value.</param>
33+
public static void SetAdditionalTemplate(DependencyObject element, DataTemplate value)
34+
{
35+
element.SetValue(AdditionalTemplateProperty, value);
36+
}
37+
38+
/// <summary>
39+
/// Gets the additional template.
40+
/// </summary>
41+
/// <param name="element">The element.</param>
42+
/// <returns>
43+
/// The <see cref="DataTemplate" />.
44+
/// </returns>
45+
public static DataTemplate GetAdditionalTemplate(DependencyObject element)
46+
{
47+
return (DataTemplate)element.GetValue(AdditionalTemplateProperty);
48+
}
49+
50+
/// <summary>
51+
/// Allows additional rendering for each tree node, outside of the rippled part of the node which responsds to user selection.
52+
/// </summary>
53+
/// <remarks>
54+
/// The content to be rendered is the same of the <see cref="TreeViewItem"/>; i.e the Header property, or
55+
/// some other content such as a view model, typically when using a <see cref="HierarchicalDataTemplate"/>.
56+
/// </remarks>
57+
public static readonly DependencyProperty AdditionalTemplateSelectorProperty = DependencyProperty.RegisterAttached(
58+
"AdditionalTemplateSelector",
59+
typeof(DataTemplateSelector),
60+
typeof(TreeViewAssist),
61+
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));
62+
63+
/// <summary>
64+
/// Sets the additional template selector.
65+
/// </summary>
66+
/// <param name="element">The element.</param>
67+
/// <param name="value">The value.</param>
68+
public static void SetAdditionalTemplateSelector(DependencyObject element, DataTemplateSelector value)
69+
{
70+
element.SetValue(AdditionalTemplateSelectorProperty, value);
71+
}
72+
73+
/// <summary>
74+
/// Gets the additional template selector.
75+
/// </summary>
76+
/// <param name="element">The element.</param>
77+
/// <returns>
78+
/// The <see cref="DataTemplateSelector" />.
79+
/// </returns>
80+
public static DataTemplateSelector GetAdditionalTemplateSelector(DependencyObject element)
81+
{
82+
return (DataTemplateSelector)element.GetValue(AdditionalTemplateSelectorProperty);
83+
}
84+
85+
private static readonly Lazy<DataTemplate> NoAdditionalTemplateProvider = new Lazy<DataTemplate>(CreateEmptyGridDataTemplate);
86+
87+
/// <summary>
88+
/// To be used at <see cref="TreeViewItem"/> level, or to be returned by <see cref="AdditionalTemplateSelector"/>
89+
/// implementors when the additional template associated with a tree should not be used.
90+
/// </summary>
91+
public static readonly DataTemplate SuppressAdditionalTemplate = NoAdditionalTemplateProvider.Value;
92+
93+
public static DataTemplate CreateEmptyGridDataTemplate()
94+
{
95+
var xaml = "<DataTemplate><Grid /></DataTemplate>";
96+
var parserContext = new ParserContext();
97+
parserContext.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
98+
parserContext.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
99+
100+
using (var memoryStream = new MemoryStream(Encoding.ASCII.GetBytes(xaml)))
101+
{
102+
return (DataTemplate)XamlReader.Load(memoryStream, parserContext);
103+
}
104+
}
105+
}
106+
}

0 commit comments

Comments
 (0)