Browse Source

Added ContentControl.ContentTemplate.

pull/540/head
Steven Kirk 10 years ago
parent
commit
0e8995e303
  1. 15
      src/Avalonia.Controls/ContentControl.cs
  2. 6
      src/Avalonia.Controls/IContentControl.cs
  3. 17
      src/Avalonia.Controls/Presenters/ContentPresenter.cs
  4. 25
      src/Avalonia.Controls/Templates/DataTemplateExtensions.cs
  5. 3
      src/Avalonia.Themes.Default/ContentControl.xaml
  6. 19
      tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

15
src/Avalonia.Controls/ContentControl.cs

@ -21,6 +21,12 @@ namespace Avalonia.Controls
public static readonly StyledProperty<object> ContentProperty =
AvaloniaProperty.Register<ContentControl, object>(nameof(Content));
/// <summary>
/// Defines the <see cref="ContentTemplate"/> property.
/// </summary>
public static readonly StyledProperty<IDataTemplate> ContentTemplateProperty =
AvaloniaProperty.Register<ContentControl, IDataTemplate>(nameof(ContentTemplate));
/// <summary>
/// Defines the <see cref="HorizontalContentAlignment"/> property.
/// </summary>
@ -51,6 +57,15 @@ namespace Avalonia.Controls
set { SetValue(ContentProperty, value); }
}
/// <summary>
/// Gets or sets the data template used to display the content of the control.
/// </summary>
public IDataTemplate ContentTemplate
{
get { return GetValue(ContentTemplateProperty); }
set { SetValue(ContentTemplateProperty, value); }
}
/// <summary>
/// Gets the presenter from the control's template.
/// </summary>

6
src/Avalonia.Controls/IContentControl.cs

@ -1,6 +1,7 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Controls.Templates;
using Avalonia.Layout;
namespace Avalonia.Controls
@ -16,6 +17,11 @@ namespace Avalonia.Controls
/// </summary>
object Content { get; set; }
/// <summary>
/// Gets or sets the data template used to display the content of the control.
/// </summary>
IDataTemplate ContentTemplate { get; set; }
/// <summary>
/// Gets or sets the horizontal alignment of the content within the control.
/// </summary>

17
src/Avalonia.Controls/Presenters/ContentPresenter.cs

@ -48,6 +48,12 @@ namespace Avalonia.Controls.Presenters
public static readonly StyledProperty<object> ContentProperty =
ContentControl.ContentProperty.AddOwner<ContentPresenter>();
/// <summary>
/// Defines the <see cref="ContentTemplate"/> property.
/// </summary>
public static readonly StyledProperty<IDataTemplate> ContentTemplateProperty =
ContentControl.ContentTemplateProperty.AddOwner<ContentPresenter>();
/// <summary>
/// Defines the <see cref="CornerRadius"/> property.
/// </summary>
@ -140,6 +146,15 @@ namespace Avalonia.Controls.Presenters
set { SetValue(ContentProperty, value); }
}
/// <summary>
/// Gets or sets the data template used to display the content of the control.
/// </summary>
public IDataTemplate ContentTemplate
{
get { return GetValue(ContentTemplateProperty); }
set { SetValue(ContentTemplateProperty, value); }
}
/// <summary>
/// Gets or sets the radius of the border rounded corners.
/// </summary>
@ -200,7 +215,7 @@ namespace Avalonia.Controls.Presenters
{
var old = Child;
var content = Content;
var result = this.MaterializeDataTemplate(content);
var result = this.MaterializeDataTemplate(content, ContentTemplate);
if (old != null)
{

25
src/Avalonia.Controls/Templates/DataTemplateExtensions.cs

@ -16,8 +16,15 @@ namespace Avalonia.Controls.Templates
/// </summary>
/// <param name="control">The control materializing the data template.</param>
/// <param name="data">The data.</param>
/// <param name="primary">
/// An optional primary template that can will be tried before the
/// <see cref="IControl.DataTemplates"/> in the tree are searched.
/// </param>
/// <returns>The data materialized as a control.</returns>
public static IControl MaterializeDataTemplate(this IControl control, object data)
public static IControl MaterializeDataTemplate(
this IControl control,
object data,
IDataTemplate primary = null)
{
if (data == null)
{
@ -33,7 +40,7 @@ namespace Avalonia.Controls.Templates
}
else
{
IDataTemplate template = control.FindDataTemplate(data);
IDataTemplate template = control.FindDataTemplate(data, primary);
IControl result;
if (template != null)
@ -57,9 +64,21 @@ namespace Avalonia.Controls.Templates
/// </summary>
/// <param name="control">The control searching for the data template.</param>
/// <param name="data">The data.</param>
/// <param name="primary">
/// An optional primary template that can will be tried before the
/// <see cref="IControl.DataTemplates"/> in the tree are searched.
/// </param>
/// <returns>The data template or null if no matching data template was found.</returns>
public static IDataTemplate FindDataTemplate(this IControl control, object data)
public static IDataTemplate FindDataTemplate(
this IControl control,
object data,
IDataTemplate primary = null)
{
if (primary?.Match(data) == true)
{
return primary;
}
foreach (var i in control.GetSelfAndLogicalAncestors().OfType<IControl>())
{
foreach (IDataTemplate dt in i.DataTemplates)

3
src/Avalonia.Themes.Default/ContentControl.xaml

@ -5,7 +5,8 @@
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Padding="{TemplateBinding Padding}"/>
</ControlTemplate>
</Setter>

19
tests/Avalonia.Controls.UnitTests/ContentControlTests.cs

@ -116,6 +116,24 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new[] { child }, target.GetLogicalChildren());
}
[Fact]
public void Should_Use_ContentTemplate_To_Create_Control()
{
var target = new ContentControl
{
Template = GetTemplate(),
ContentTemplate = new FuncDataTemplate<string>(_ => new Canvas()),
};
target.Content = "Foo";
target.ApplyTemplate();
((ContentPresenter)target.Presenter).UpdateChild();
var child = target.Presenter.Child;
Assert.IsType<Canvas>(child);
}
[Fact]
public void DataTemplate_Created_Control_Should_Be_Logical_Child_After_ApplyTemplate()
{
@ -266,6 +284,7 @@ namespace Avalonia.Controls.UnitTests
{
Name = "PART_ContentPresenter",
[~ContentPresenter.ContentProperty] = parent[~ContentControl.ContentProperty],
[~ContentPresenter.ContentTemplateProperty] = parent[~ContentControl.ContentTemplateProperty],
}
};
});

Loading…
Cancel
Save