csharpc-sharpdotnetxamlavaloniauicross-platformcross-platform-xamlavaloniaguimulti-platformuser-interfacedotnetcore
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
159 lines
5.3 KiB
159 lines
5.3 KiB
// -----------------------------------------------------------------------
|
|
// <copyright file="ContentPresenter.cs" company="Steven Kirk">
|
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
|
// </copyright>
|
|
// -----------------------------------------------------------------------
|
|
|
|
namespace Perspex.Controls
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using Perspex.Media;
|
|
|
|
public class ContentPresenter : Control, IVisual
|
|
{
|
|
public static readonly PerspexProperty<object> ContentProperty =
|
|
ContentControl.ContentProperty.AddOwner<Control>();
|
|
|
|
public static readonly PerspexProperty<Func<object, Visual>> DataTemplateProperty =
|
|
PerspexProperty.Register<ContentPresenter, Func<object, Visual>>("DataTemplate");
|
|
|
|
private Visual visualChild;
|
|
|
|
public ContentPresenter()
|
|
{
|
|
this.GetObservableWithHistory(ContentProperty).Subscribe(x =>
|
|
{
|
|
if (x.Item1 is Control)
|
|
{
|
|
((IVisual)x.Item1).VisualParent = null;
|
|
((ILogical)x.Item1).LogicalParent = null;
|
|
}
|
|
|
|
if (x.Item2 is Control)
|
|
{
|
|
((IVisual)x.Item2).VisualParent = this;
|
|
((ILogical)x.Item2).LogicalParent = this;
|
|
}
|
|
});
|
|
}
|
|
|
|
public object Content
|
|
{
|
|
get { return this.GetValue(ContentProperty); }
|
|
set { this.SetValue(ContentProperty, value); }
|
|
}
|
|
|
|
public Func<object, Visual> DataTemplate
|
|
{
|
|
get { return this.GetValue(DataTemplateProperty); }
|
|
set { this.SetValue(DataTemplateProperty, value); }
|
|
}
|
|
|
|
IEnumerable<IVisual> IVisual.VisualChildren
|
|
{
|
|
get
|
|
{
|
|
object content = this.Content;
|
|
var dataTemplate = this.DataTemplate;
|
|
|
|
if (this.visualChild == null && content != null)
|
|
{
|
|
if (content is Visual)
|
|
{
|
|
this.visualChild = (Visual)content;
|
|
}
|
|
else if (dataTemplate != null)
|
|
{
|
|
this.visualChild = dataTemplate(this);
|
|
}
|
|
else
|
|
{
|
|
this.visualChild = new TextBlock
|
|
{
|
|
Text = content.ToString(),
|
|
};
|
|
}
|
|
|
|
if (this.visualChild != null)
|
|
{
|
|
((IVisual)this.visualChild).VisualParent = this;
|
|
}
|
|
}
|
|
|
|
return Enumerable.Repeat(this.visualChild, this.visualChild != null ? 1 : 0);
|
|
}
|
|
}
|
|
|
|
protected override Size ArrangeOverride(Size finalSize)
|
|
{
|
|
Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control;
|
|
|
|
if (child != null)
|
|
{
|
|
double left;
|
|
double top;
|
|
double width;
|
|
double height;
|
|
|
|
switch (child.HorizontalAlignment)
|
|
{
|
|
case HorizontalAlignment.Left:
|
|
left = 0;
|
|
width = child.DesiredSize.Value.Width;
|
|
break;
|
|
case HorizontalAlignment.Center:
|
|
left = (finalSize.Width / 2) - (child.DesiredSize.Value.Width / 2);
|
|
width = child.DesiredSize.Value.Width;
|
|
break;
|
|
case HorizontalAlignment.Right:
|
|
left = finalSize.Width - child.DesiredSize.Value.Width;
|
|
width = child.DesiredSize.Value.Width;
|
|
break;
|
|
default:
|
|
left = 0;
|
|
width = finalSize.Width;
|
|
break;
|
|
}
|
|
|
|
switch (child.VerticalAlignment)
|
|
{
|
|
case VerticalAlignment.Top:
|
|
top = 0;
|
|
height = child.DesiredSize.Value.Height;
|
|
break;
|
|
case VerticalAlignment.Center:
|
|
top = (finalSize.Height / 2) - (child.DesiredSize.Value.Height / 2);
|
|
height = child.DesiredSize.Value.Height;
|
|
break;
|
|
case VerticalAlignment.Bottom:
|
|
top = finalSize.Height - child.DesiredSize.Value.Height;
|
|
height = child.DesiredSize.Value.Height;
|
|
break;
|
|
default:
|
|
top = 0;
|
|
height = finalSize.Height;
|
|
break;
|
|
}
|
|
|
|
child.Arrange(new Rect(left, top, width, height));
|
|
}
|
|
|
|
return finalSize;
|
|
}
|
|
|
|
protected override Size MeasureOverride(Size availableSize)
|
|
{
|
|
Control child = ((IVisual)this).VisualChildren.SingleOrDefault() as Control;
|
|
|
|
if (child != null)
|
|
{
|
|
child.Measure(availableSize);
|
|
return child.DesiredSize.Value;
|
|
}
|
|
|
|
return new Size();
|
|
}
|
|
}
|
|
}
|
|
|