Browse Source

Tidied up Presenter/TemplatedParent logic a bit.

pull/39/head
Steven Kirk 12 years ago
parent
commit
b28b5e5a23
  1. 20
      Perspex.Controls.UnitTests/ItemsControlTests.cs
  2. 64
      Perspex.Controls.UnitTests/TemplatedControlTests.cs
  3. 2
      Perspex.Controls/Control.cs
  4. 5
      Perspex.Controls/ControlTemplate.cs
  5. 1
      Perspex.Controls/Perspex.Controls.csproj
  6. 2
      Perspex.Controls/Presenters/ContentPresenter.cs
  7. 24
      Perspex.Controls/Presenters/IPresenter.cs
  8. 4
      Perspex.Controls/Presenters/ItemsPresenter.cs
  9. 2
      Perspex.Controls/Presenters/ScrollContentPresenter.cs
  10. 4
      Perspex.Controls/Presenters/TextPresenter.cs
  11. 15
      Perspex.Controls/Primitives/TemplatedControl.cs
  12. 2
      Perspex.Themes.Default/TabStripStyle.cs
  13. 1
      Perspex.Themes.Default/TextBoxStyle.cs

20
Perspex.Controls.UnitTests/ItemsControlTests.cs

@ -10,11 +10,9 @@ namespace Perspex.Controls.UnitTests
using System.Collections.Specialized;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Perspex.Collections;
using Perspex.Controls;
using Perspex.Controls.Presenters;
using Perspex.Layout;
using Perspex.Platform;
using Perspex.Styling;
using Perspex.VisualTree;
@ -25,6 +23,21 @@ namespace Perspex.Controls.UnitTests
[TestClass]
public class ItemsControlTests
{
[TestMethod]
public void Panel_Should_Have_TemplatedParent_Set_To_ItemsPresenter()
{
var target = new ItemsControl();
target.Template = this.GetTemplate();
target.Items = new[] { "Foo" };
target.ApplyTemplate();
var presenter = target.GetTemplateControls().OfType<ItemsPresenter>().Single();
var panel = presenter.GetTemplateControls().OfType<StackPanel>().Single();
Assert.AreEqual(presenter, panel.TemplatedParent);
}
[TestMethod]
public void Item_Should_Have_TemplatedParent_Set_To_Null()
{
@ -34,7 +47,8 @@ namespace Perspex.Controls.UnitTests
target.Items = new[] { "Foo" };
target.ApplyTemplate();
var panel = target.GetTemplateControls().OfType<StackPanel>().Single();
var presenter = target.GetTemplateControls().OfType<ItemsPresenter>().Single();
var panel = presenter.GetTemplateControls().OfType<StackPanel>().Single();
var item = (TextBlock)panel.GetVisualChildren().First();
Assert.IsNull(item.TemplatedParent);

64
Perspex.Controls.UnitTests/TemplatedControlTests.cs

@ -15,6 +15,7 @@ namespace Perspex.Controls.UnitTests
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Perspex.Controls;
using Perspex.Controls.Presenters;
using Perspex.Controls.Primitives;
using Perspex.Styling;
using Perspex.VisualTree;
@ -213,6 +214,69 @@ namespace Perspex.Controls.UnitTests
Assert.AreEqual(target, textBlock.TemplatedParent);
}
[TestMethod]
public void Presenter_Children_Should_Not_Have_TemplatedParent_Set()
{
var target = new TestTemplatedControl
{
Template = new ControlTemplate(_ =>
{
return new ContentPresenter
{
Content = new TextBlock
{
}
};
}),
};
target.ApplyTemplate();
var presenter = target.GetTemplateControls().OfType<ContentPresenter>().Single();
var textBlock = (TextBlock)presenter.Child;
Assert.AreEqual(target, presenter.TemplatedParent);
Assert.IsNull(textBlock.TemplatedParent);
}
[TestMethod]
public void Nested_Templated_Controls_Have_Correct_TemplatedParent()
{
var target = new TestTemplatedControl
{
Template = new ControlTemplate(_ =>
{
return new ContentControl
{
Template = new ControlTemplate(parent =>
{
return new Border
{
Content = new ContentPresenter
{
[~ContentPresenter.ContentProperty] = parent.GetObservable(ContentControl.ContentProperty),
}
};
}),
Content = new TextBlock
{
}
};
}),
};
target.ApplyTemplate();
var contentControl = target.GetTemplateControls().OfType<ContentControl>().Single();
var border = contentControl.GetTemplateControls().OfType<Border>().Single();
var presenter = contentControl.GetTemplateControls().OfType<ContentPresenter>().Single();
var textBlock = (TextBlock)presenter.Content;
Assert.AreEqual(target, contentControl.TemplatedParent);
Assert.AreEqual(contentControl, border.TemplatedParent);
Assert.AreEqual(contentControl, presenter.TemplatedParent);
Assert.AreEqual(target, textBlock.TemplatedParent);
}
}
}

2
Perspex.Controls/Control.cs

@ -27,7 +27,7 @@ namespace Perspex.Controls
PerspexProperty.Register<Control, object>("Tag");
public static readonly PerspexProperty<ITemplatedControl> TemplatedParentProperty =
PerspexProperty.Register<Control, ITemplatedControl>("TemplatedParent", inherits: true);
PerspexProperty.Register<Control, ITemplatedControl>("TemplatedParent");
public static readonly RoutedEvent<RequestBringIntoViewEventArgs> RequestBringIntoViewEvent =
RoutedEvent.Register<Control, RequestBringIntoViewEventArgs>("RequestBringIntoView", RoutingStrategy.Bubble);

5
Perspex.Controls/ControlTemplate.cs

@ -7,8 +7,6 @@
namespace Perspex.Controls
{
using System;
using System.Linq;
using Perspex.Layout;
using Perspex.Styling;
public class ControlTemplate
@ -34,8 +32,7 @@ namespace Perspex.Controls
{
Contract.Requires<NullReferenceException>(templatedParent != null);
Control root = this.build(templatedParent);
root.TemplatedParent = templatedParent;
var root = this.build(templatedParent);
return root;
}
}

1
Perspex.Controls/Perspex.Controls.csproj

@ -43,6 +43,7 @@
<Compile Include="Platform\ITopLevelImpl.cs" />
<Compile Include="Popup.cs" />
<Compile Include="IDataTemplate.cs" />
<Compile Include="Presenters\IPresenter.cs" />
<Compile Include="RadioButton.cs" />
<Compile Include="CheckBox.cs" />
<Compile Include="ColumnDefinition.cs" />

2
Perspex.Controls/Presenters/ContentPresenter.cs

@ -13,7 +13,7 @@ namespace Perspex.Controls.Presenters
using Perspex.Controls.Primitives;
using Perspex.Media;
public class ContentPresenter : Control, IVisual
public class ContentPresenter : Control, IVisual, IPresenter
{
public static readonly PerspexProperty<object> ContentProperty =
ContentControl.ContentProperty.AddOwner<ContentPresenter>();

24
Perspex.Controls/Presenters/IPresenter.cs

@ -0,0 +1,24 @@
// -----------------------------------------------------------------------
// <copyright file="IPresenter.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls.Presenters
{
using Perspex.Controls.Primitives;
/// <summary>
/// Interface for presenters such as <see cref="ContentPresenter"/> and
/// <see cref="ItemsPresenter"/>.
/// </summary>
/// <remarks>
/// A presenter is the gateway between a templated control and its content. When
/// a control which implements <see cref="IPresenter"/> is found in the template
/// of a <see cref="TemplatedControl"/> then that signals that the visual child
/// of the presenter is not a part of the template.
/// </remarks>
public interface IPresenter : IVisual
{
}
}

4
Perspex.Controls/Presenters/ItemsPresenter.cs

@ -11,8 +11,9 @@ namespace Perspex.Controls.Presenters
using System.Collections.Specialized;
using System.Reactive.Linq;
using Perspex.Controls.Generators;
using Perspex.Styling;
public class ItemsPresenter : Control, IVisual
public class ItemsPresenter : Control, IVisual, IPresenter, ITemplatedControl
{
public static readonly PerspexProperty<IEnumerable> ItemsProperty =
ItemsControl.ItemsProperty.AddOwner<ItemsPresenter>();
@ -65,6 +66,7 @@ namespace Perspex.Controls.Presenters
{
this.ClearVisualChildren();
this.panel = this.ItemsPanel.Build();
this.panel.TemplatedParent = this;
((IItemsPanel)this.panel).ChildLogicalParent = this.TemplatedParent as ILogical;
this.AddVisualChild(this.panel);
this.createdPanel = true;

2
Perspex.Controls/Presenters/ScrollContentPresenter.cs

@ -12,7 +12,7 @@ namespace Perspex.Controls.Presenters
using Perspex.Layout;
using Perspex.VisualTree;
public class ScrollContentPresenter : ContentPresenter
public class ScrollContentPresenter : ContentPresenter, IPresenter
{
public static readonly PerspexProperty<Size> ExtentProperty =
ScrollViewer.ExtentProperty.AddOwner<ScrollContentPresenter>();

4
Perspex.Controls/Presenters/TextPresenter.cs

@ -4,7 +4,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
namespace Perspex.Controls.Presenters
{
using System;
using System.Collections.Generic;
@ -17,7 +17,7 @@ namespace Perspex.Controls
using Perspex.Threading;
using Perspex.VisualTree;
public class TextPresenter : TextBlock
public class TextPresenter : TextBlock, IPresenter
{
public static readonly PerspexProperty<bool> AcceptsReturnProperty =
TextBox.AcceptsReturnProperty.AddOwner<TextPresenter>();

15
Perspex.Controls/Primitives/TemplatedControl.cs

@ -8,6 +8,7 @@ namespace Perspex.Controls.Primitives
{
using System;
using System.Linq;
using Perspex.Controls.Presenters;
using Perspex.Media;
using Perspex.Styling;
using Perspex.VisualTree;
@ -117,6 +118,7 @@ namespace Perspex.Controls.Primitives
this.GetHashCode());
var child = this.Template.Build(this);
this.SetTemplatedParent(child);
this.AddVisualChild(child);
child.Parent = this;
@ -187,5 +189,18 @@ namespace Perspex.Controls.Primitives
protected virtual void OnTemplateApplied()
{
}
private void SetTemplatedParent(Control control)
{
control.TemplatedParent = this;
if (!(control is IPresenter))
{
foreach (var child in control.GetVisualChildren().OfType<Control>())
{
this.SetTemplatedParent(child);
}
}
}
}
}

2
Perspex.Themes.Default/TabStripStyle.cs

@ -25,7 +25,7 @@ namespace Perspex.Themes.Default
new Setter(TabStrip.TemplateProperty, ControlTemplate.Create<TabStrip>(this.Template)),
},
},
new Style(x => x.OfType<TabStrip>().Template().OfType<StackPanel>())
new Style(x => x.OfType<TabStrip>().Template().OfType<ItemsPresenter>().Template().OfType<StackPanel>())
{
Setters = new[]
{

1
Perspex.Themes.Default/TextBoxStyle.cs

@ -12,6 +12,7 @@ namespace Perspex.Themes.Default
using Perspex.Media;
using Perspex.Controls.Shapes;
using Perspex.Styling;
using Perspex.Controls.Presenters;
public class TextBoxStyle : Styles
{

Loading…
Cancel
Save