diff --git a/Perspex/Controls/Control.cs b/Perspex/Controls/Control.cs index 1d6f45c5b2..cc41890c05 100644 --- a/Perspex/Controls/Control.cs +++ b/Perspex/Controls/Control.cs @@ -190,11 +190,11 @@ namespace Perspex.Controls get { return Enumerable.Empty(); } } - protected override void AttachedToVisualTree() + protected override void OnAttachedToVisualTree() { IStyler styler = Locator.Current.GetService(); styler.ApplyStyles(this); - base.AttachedToVisualTree(); + base.OnAttachedToVisualTree(); } protected void AddPseudoClass(PerspexProperty property, string className) diff --git a/Perspex/Controls/DataTemplate.cs b/Perspex/Controls/DataTemplate.cs index 41efe6e254..9f9de2b477 100644 --- a/Perspex/Controls/DataTemplate.cs +++ b/Perspex/Controls/DataTemplate.cs @@ -46,13 +46,23 @@ namespace Perspex.Controls public class DataTemplate : DataTemplate { public DataTemplate(Func build) - : base(typeof(T), o => build((T)o)) + : base(typeof(T), Cast(build)) { } public DataTemplate(Func match, Func build) - : base(o => (o is T) ? match((T)o) : false, o => build((T)o)) + : base(CastMatch(match), Cast(build)) { } + + private static Func CastMatch(Func f) + { + return o => (o is T) ? f((T)o) : false; + } + + private static Func Cast(Func f) + { + return o => f((T)o); + } } } diff --git a/Perspex/Controls/TreeDataTemplate.cs b/Perspex/Controls/TreeDataTemplate.cs index 5b9ca4fab6..5a78fea93f 100644 --- a/Perspex/Controls/TreeDataTemplate.cs +++ b/Perspex/Controls/TreeDataTemplate.cs @@ -26,16 +26,38 @@ namespace Perspex.Controls { } + public TreeDataTemplate( + Type type, + Func build, + Func itemsSelector, + Func isExpanded) + : this(o => IsInstance(o, type), build, itemsSelector, isExpanded) + { + } + public TreeDataTemplate( Func match, Func build, Func itemsSelector) + : this(match, build, itemsSelector, _ => false) + { + this.ItemsSelector = itemsSelector; + } + + public TreeDataTemplate( + Func match, + Func build, + Func itemsSelector, + Func isExpanded) : base(match, build) { this.ItemsSelector = itemsSelector; + this.IsExpanded = isExpanded; } public Func ItemsSelector { get; private set; } + + public Func IsExpanded { get; private set; } } public class TreeDataTemplate : TreeDataTemplate @@ -43,7 +65,15 @@ namespace Perspex.Controls public TreeDataTemplate( Func build, Func itemsSelector) - : base(typeof(T), o => build((T)o), o => itemsSelector((T)o)) + : base(typeof(T), Cast(build), Cast(itemsSelector)) + { + } + + public TreeDataTemplate( + Func build, + Func itemsSelector, + Func isExpanded) + : base(typeof(T), Cast(build), Cast(itemsSelector), Cast(isExpanded)) { } @@ -51,8 +81,27 @@ namespace Perspex.Controls Func match, Func build, Func itemsSelector) - : base(o => (o is T) ? match((T)o) : false, o => build((T)o), o => itemsSelector((T)o)) + : base(CastMatch(match), Cast(build), Cast(itemsSelector)) + { + } + + public TreeDataTemplate( + Func match, + Func build, + Func itemsSelector, + Func isExpanded) + : base(CastMatch(match), Cast(build), Cast(itemsSelector), Cast(isExpanded)) + { + } + + private static Func CastMatch(Func f) + { + return o => (o is T) ? f((T)o) : false; + } + + private static Func Cast(Func f) { + return o => f((T)o); } } } diff --git a/Perspex/Controls/TreeView.cs b/Perspex/Controls/TreeView.cs index 95bb5577ba..941982448e 100644 --- a/Perspex/Controls/TreeView.cs +++ b/Perspex/Controls/TreeView.cs @@ -25,6 +25,7 @@ namespace Perspex.Controls { Header = template.Build(item), Items = template.ItemsSelector(item), + IsExpanded = template.IsExpanded(item), }; } diff --git a/Perspex/Controls/TreeViewItem.cs b/Perspex/Controls/TreeViewItem.cs index 1ad0a27dd2..b2ab2bbd42 100644 --- a/Perspex/Controls/TreeViewItem.cs +++ b/Perspex/Controls/TreeViewItem.cs @@ -11,10 +11,30 @@ namespace Perspex.Controls public static readonly PerspexProperty IsExpandedProperty = PerspexProperty.Register("IsExpanded"); + TreeView parent; + public bool IsExpanded { get { return this.GetValue(IsExpandedProperty); } set { this.SetValue(IsExpandedProperty, value); } } + + protected override Control CreateItemControlOverride(object item) + { + if (this.parent != null) + { + return this.parent.CreateItemControl(item); + } + else + { + return null; + } + } + + protected override void OnAttachedToVisualTree() + { + base.OnAttachedToVisualTree(); + this.parent = this.GetVisualParent().TemplatedParent as TreeView; + } } } diff --git a/Perspex/Visual.cs b/Perspex/Visual.cs index 5fa310fac2..3b5387f4db 100644 --- a/Perspex/Visual.cs +++ b/Perspex/Visual.cs @@ -64,11 +64,11 @@ namespace Perspex IVisual oldValue = this.visualParent; this.visualParent = value; this.InheritanceParent = (PerspexObject)value; - this.VisualParentChanged(oldValue, value); + this.OnVisualParentChanged(oldValue, value); if (this.GetVisualAncestor() != null) { - this.AttachedToVisualTree(); + this.NotifyAttachedToVisualTree(); } } } @@ -104,21 +104,27 @@ namespace Perspex Contract.Requires(context != null); } - protected virtual void AttachedToVisualTree() + protected virtual void OnAttachedToVisualTree() + { + } + + protected virtual void OnVisualParentChanged(IVisual oldValue, IVisual newValue) + { + } + + private void NotifyAttachedToVisualTree() { this.Log().Debug(string.Format( "Attached {0} (#{1:x8}) to visual tree", this.GetType().Name, this.GetHashCode())); + this.OnAttachedToVisualTree(); + foreach (Visual child in ((IVisual)this).ExistingVisualChildren.OfType()) { - child.AttachedToVisualTree(); + child.NotifyAttachedToVisualTree(); } } - - protected virtual void VisualParentChanged(IVisual oldValue, IVisual newValue) - { - } } } diff --git a/Perspex/VisualExtensions.cs b/Perspex/VisualExtensions.cs index f6d10b6816..3cb5413689 100644 --- a/Perspex/VisualExtensions.cs +++ b/Perspex/VisualExtensions.cs @@ -126,6 +126,16 @@ namespace Perspex } } + public static IVisual GetVisualParent(this IVisual visual) + { + return visual.VisualParent; + } + + public static T GetVisualParent(this IVisual visual) where T : class + { + return visual.VisualParent as T; + } + public static IEnumerable GetVisualSiblings(this IVisual visual) { IVisual parent = visual.VisualParent; diff --git a/TestApplication/Program.cs b/TestApplication/Program.cs index 977e682efe..ae78e29df1 100644 --- a/TestApplication/Program.cs +++ b/TestApplication/Program.cs @@ -88,7 +88,8 @@ namespace TestApplication { new TreeDataTemplate( x => new TextBlock { Text = x.Name }, - x => x.Children), + x => x.Children, + x => true), }, };