diff --git a/src/Perspex.Base/PerspexObjectExtensions.cs b/src/Perspex.Base/PerspexObjectExtensions.cs index 6cd75b691d..cbfb8e45e7 100644 --- a/src/Perspex.Base/PerspexObjectExtensions.cs +++ b/src/Perspex.Base/PerspexObjectExtensions.cs @@ -164,6 +164,36 @@ namespace Perspex return result; } + /// + /// Binds a property on an to an . + /// + /// The object. + /// The property to bind. + /// The binding. + /// An which can be used to cancel the binding. + public static IDisposable Bind( + this IPerspexObject o, + PerspexProperty property, + IBinding binding) + { + Contract.Requires(o != null); + Contract.Requires(property != null); + Contract.Requires(binding != null); + + var mode = binding.Mode; + + if (mode == BindingMode.Default) + { + mode = property.DefaultBindingMode; + } + + return o.Bind( + property, + binding.CreateSubject(o, property), + mode, + binding.Priority); + } + /// /// Binds a property to a subject according to a . /// diff --git a/src/Perspex.Controls/ControlExtensions.cs b/src/Perspex.Controls/ControlExtensions.cs index db11bff51e..a04bffde9f 100644 --- a/src/Perspex.Controls/ControlExtensions.cs +++ b/src/Perspex.Controls/ControlExtensions.cs @@ -14,36 +14,6 @@ namespace Perspex.Controls /// public static class ControlExtensions { - /// - /// Binds a property on an to an . - /// - /// The object. - /// The property to bind. - /// The binding. - /// An which can be used to cancel the binding. - public static IDisposable Bind( - this IControl o, - PerspexProperty property, - IBinding binding) - { - Contract.Requires(o != null); - Contract.Requires(property != null); - Contract.Requires(binding != null); - - var mode = binding.Mode; - - if (mode == BindingMode.Default) - { - mode = property.DefaultBindingMode; - } - - return o.Bind( - property, - binding.CreateSubject(o, property), - mode, - binding.Priority); - } - /// /// Tries to being the control into view. /// diff --git a/src/Perspex.Controls/TreeView.cs b/src/Perspex.Controls/TreeView.cs index 4b7b1f986a..0a83891bc8 100644 --- a/src/Perspex.Controls/TreeView.cs +++ b/src/Perspex.Controls/TreeView.cs @@ -46,8 +46,27 @@ namespace Perspex.Controls /// public object SelectedItem { - get { return _selectedItem; } - set { SetAndRaise(SelectedItemProperty, ref _selectedItem, value); } + get + { + return _selectedItem; + } + + set + { + if (_selectedItem != null) + { + var container = ItemContainerGenerator.Index.ContainerFromItem(_selectedItem); + MarkContainerSelected(container, false); + } + + SetAndRaise(SelectedItemProperty, ref _selectedItem, value); + + if (_selectedItem != null) + { + var container = ItemContainerGenerator.Index.ContainerFromItem(_selectedItem); + MarkContainerSelected(container, true); + } + } } /// diff --git a/src/Perspex.Styling/Styling/Setter.cs b/src/Perspex.Styling/Styling/Setter.cs index b224382f4a..675c21789a 100644 --- a/src/Perspex.Styling/Styling/Setter.cs +++ b/src/Perspex.Styling/Styling/Setter.cs @@ -79,7 +79,7 @@ namespace Perspex.Styling { if (activator == null) { - Bind(control, Property, binding); + control.Bind(Property, binding); } else { @@ -102,15 +102,10 @@ namespace Perspex.Styling } } - private void Bind(IStyleable control, PerspexProperty property, IBinding binding) - { - Bind(control, property, binding, binding.CreateSubject(control, property)); - } - private void Bind( - IStyleable control, - PerspexProperty property, - IBinding binding, + IStyleable control, + PerspexProperty property, + IBinding binding, ISubject subject) { var mode = binding.Mode; diff --git a/tests/Perspex.Controls.UnitTests/TreeViewTests.cs b/tests/Perspex.Controls.UnitTests/TreeViewTests.cs index 8ee0d73a1e..f28cabe0f3 100644 --- a/tests/Perspex.Controls.UnitTests/TreeViewTests.cs +++ b/tests/Perspex.Controls.UnitTests/TreeViewTests.cs @@ -107,6 +107,31 @@ namespace Perspex.Controls.UnitTests Assert.True(container.IsSelected); } + [Fact] + public void Setting_SelectedItem_Should_Set_Container_Selected() + { + var tree = CreateTestTreeData(); + var target = new TreeView + { + Template = CreateTreeViewTemplate(), + Items = tree, + DataTemplates = CreateNodeDataTemplate(), + }; + + var visualRoot = new TestRoot(); + visualRoot.Child = target; + ApplyTemplates(target); + + var item = tree[0].Children[1].Children[0]; + var container = (TreeViewItem)target.ItemContainerGenerator.Index.ContainerFromItem(item); + + Assert.NotNull(container); + + target.SelectedItem = item; + + Assert.True(container.IsSelected); + } + [Fact] public void LogicalChildren_Should_Be_Set() {