Browse Source

Fixed controls getting styled multiple times.

pull/4/head
Steven Kirk 12 years ago
parent
commit
3d8d93d1eb
  1. 80
      Perspex.UnitTests/Controls/ContentControlTests.cs
  2. 2
      Perspex.UnitTests/Perspex.UnitTests.csproj
  3. 6
      Perspex.UnitTests/Styling/TestTemplatedControl.cs
  4. 27
      Perspex.UnitTests/TestRoot.cs
  5. 2
      Perspex/Controls/ContentControl.cs
  6. 9
      Perspex/Controls/Control.cs
  7. 5
      Perspex/Controls/Decorator.cs
  8. 9
      Perspex/Controls/ITemplatedControl.cs
  9. 5
      Perspex/Controls/TemplatedControl.cs
  10. 4
      Perspex/IVisual.cs
  11. 7
      Perspex/Visual.cs
  12. 54
      TestApplication/Program.cs

80
Perspex.UnitTests/Controls/ContentControlTests.cs

@ -0,0 +1,80 @@
// -----------------------------------------------------------------------
// <copyright file="ContentControlTests.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.UnitTests.Controls
{
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
using Perspex.Controls;
using Perspex.Layout;
using Perspex.Styling;
using Perspex.Themes.Default;
using Splat;
[TestClass]
public class ContentControlTests
{
[TestMethod]
public void Template_Should_Be_Instantiated()
{
var target = new ContentControl();
target.Content = "Foo";
target.Template = this.GetTemplate();
var child = ((IVisual)target).VisualChildren.Single();
Assert.IsInstanceOfType(child, typeof(Border));
child = child.VisualChildren.Single();
Assert.IsInstanceOfType(child, typeof(ContentPresenter));
child = child.VisualChildren.Single();
Assert.IsInstanceOfType(child, typeof(TextBlock));
}
[TestMethod]
public void Templated_Children_Should_Be_Styled()
{
using (Locator.CurrentMutable.WithResolver())
{
var root = new TestRoot();
var target = new ContentControl();
var styler = new Mock<IStyler>();
Locator.CurrentMutable.Register(() => styler.Object, typeof(IStyler));
target.Content = "Foo";
target.Template = this.GetTemplate();
root.Content = target;
this.ApplyTemplate(target);
styler.Verify(x => x.ApplyStyles(It.IsAny<ContentControl>()), Times.Once());
styler.Verify(x => x.ApplyStyles(It.IsAny<Border>()), Times.Once());
styler.Verify(x => x.ApplyStyles(It.IsAny<ContentPresenter>()), Times.Once());
styler.Verify(x => x.ApplyStyles(It.IsAny<TextBlock>()), Times.Once());
}
}
private void ApplyTemplate(IVisual visual)
{
foreach (IVisual child in visual.VisualChildren)
{
this.ApplyTemplate(child);
}
}
private ControlTemplate GetTemplate()
{
return new ControlTemplate(parent =>
{
Border border = new Border();
border.Background = new Perspex.Media.SolidColorBrush(0xffffffff);
ContentPresenter contentPresenter = new ContentPresenter();
contentPresenter.SetValue(ContentPresenter.ContentProperty, parent.GetObservable(ContentControl.ContentProperty));
border.Content = contentPresenter;
return border;
});
}
}
}

2
Perspex.UnitTests/Perspex.UnitTests.csproj

@ -68,6 +68,7 @@
</Otherwise>
</Choose>
<ItemGroup>
<Compile Include="Controls\ContentControlTests.cs" />
<Compile Include="Controls\ControlTests.cs" />
<Compile Include="Controls\TemplatedControlTests.cs" />
<Compile Include="PerspexPropertyTests.cs" />
@ -85,6 +86,7 @@
<Compile Include="Styling\TestSelectors.cs" />
<Compile Include="Styling\TestObservable.cs" />
<Compile Include="Styling\TestControlBase.cs" />
<Compile Include="TestRoot.cs" />
<Compile Include="TestSubject.cs" />
<Compile Include="TestObserver.cs" />
</ItemGroup>

6
Perspex.UnitTests/Styling/TestTemplatedControl.cs

@ -6,6 +6,7 @@
namespace Perspex.UnitTests.Styling
{
using System;
using System.Collections.Generic;
using Perspex.Controls;
using Perspex.Styling;
@ -32,6 +33,11 @@ namespace Perspex.UnitTests.Styling
get;
}
public IObservable<T> GetObservable<T>(PerspexProperty<T> property)
{
throw new NotImplementedException();
}
public abstract void SetValue(PerspexProperty property, object value, System.IObservable<bool> activator);
}
}

27
Perspex.UnitTests/TestRoot.cs

@ -0,0 +1,27 @@
// -----------------------------------------------------------------------
// <copyright file="TestRoot.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.UnitTests
{
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using Perspex.Controls;
using Perspex.Layout;
internal class TestRoot : Decorator, ILayoutRoot
{
public Size ClientSize
{
get { throw new NotImplementedException(); }
}
public ILayoutManager LayoutManager
{
get { throw new NotImplementedException(); }
}
}
}

2
Perspex/Controls/ContentControl.cs

@ -10,7 +10,7 @@ namespace Perspex.Controls
using System.Collections.Generic;
using System.Linq;
public abstract class ContentControl : TemplatedControl
public class ContentControl : TemplatedControl
{
public static readonly PerspexProperty<object> ContentProperty =
PerspexProperty.Register<ContentControl, object>("Content");

9
Perspex/Controls/Control.cs

@ -244,14 +244,7 @@ namespace Perspex.Controls
public ILayoutRoot GetLayoutRoot()
{
Control c = this;
while (c != null && !(c is ILayoutRoot))
{
c = c.Parent;
}
return (ILayoutRoot)c;
return this.GetVisualAncestorOrSelf<ILayoutRoot>();
}
public void Arrange(Rect rect)

5
Perspex/Controls/Decorator.cs

@ -43,6 +43,11 @@ namespace Perspex.Controls
set { this.SetValue(PaddingProperty, value); }
}
IEnumerable<IVisual> IVisual.ExistingVisualChildren
{
get { return ((IVisual)this).VisualChildren; }
}
IEnumerable<IVisual> IVisual.VisualChildren
{
get

9
Perspex/Controls/ITemplatedControl.cs

@ -6,10 +6,19 @@
namespace Perspex.Controls
{
using System;
using System.Collections.Generic;
public interface ITemplatedControl
{
/// <summary>
/// Gets an observable for a <see cref="PerspexProperty"/>.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="property">The property to get the observable for.</param>
/// <returns>The observable.</returns>
IObservable<T> GetObservable<T>(PerspexProperty<T> property);
IEnumerable<IVisual> VisualChildren { get; }
}
}

5
Perspex/Controls/TemplatedControl.cs

@ -24,6 +24,11 @@ namespace Perspex.Controls
set { this.SetValue(TemplateProperty, value); }
}
IEnumerable<IVisual> IVisual.ExistingVisualChildren
{
get { return Enumerable.Repeat(this.visualChild, this.visualChild != null ? 1 : 0); }
}
IEnumerable<IVisual> ITemplatedControl.VisualChildren
{
get

4
Perspex/IVisual.cs

@ -13,7 +13,9 @@ namespace Perspex
public interface IVisual
{
Rect Bounds { get; }
IEnumerable<IVisual> ExistingVisualChildren { get; }
IEnumerable<IVisual> VisualChildren { get; }
IVisual VisualParent { get; set; }

7
Perspex/Visual.cs

@ -51,6 +51,11 @@ namespace Perspex
}
}
IEnumerable<IVisual> IVisual.ExistingVisualChildren
{
get { return Enumerable.Empty<Visual>(); }
}
IEnumerable<ILogical> ILogical.LogicalChildren
{
get { return new ILogical[0]; }
@ -92,7 +97,7 @@ namespace Perspex
protected virtual void AttachedToVisualTree()
{
foreach (Visual child in ((IVisual)this).VisualChildren.OfType<Visual>())
foreach (Visual child in ((IVisual)this).ExistingVisualChildren.OfType<Visual>())
{
child.AttachedToVisualTree();
}

54
TestApplication/Program.cs

@ -19,7 +19,6 @@ namespace TestApplication
{
class TestLogger : ILogger
{
public LogLevel Level
{
get;
@ -51,33 +50,34 @@ namespace TestApplication
Window window = new Window
{
Content = new TestBorder
{
Styles = new Styles
{
new Style(new Selector().OfType<TestBorder>())
{
Setters = new[]
{
new Setter(TestBorder.BackgroundProperty, new SolidColorBrush(0xff0000ff)),
}
},
new Style(new Selector().OfType<TestBorder>().Class(":mouseover"))
{
Setters = new[]
{
new Setter(TestBorder.BackgroundProperty, new SolidColorBrush(0xffff0000)),
}
},
}
},
//Content = new Button
//{
// Content = "Hello World",
// HorizontalAlignment = HorizontalAlignment.Center,
// VerticalAlignment = VerticalAlignment.Center,
//Content = new TestBorder
//{
// Margin = new Thickness(10),
// Styles = new Styles
// {
// new Style(new Selector().OfType<TestBorder>())
// {
// Setters = new[]
// {
// new Setter(TestBorder.BackgroundProperty, new SolidColorBrush(0xff0000ff)),
// }
// },
// new Style(new Selector().OfType<TestBorder>().Class(":mouseover"))
// {
// Setters = new[]
// {
// new Setter(TestBorder.BackgroundProperty, new SolidColorBrush(0xffff0000)),
// }
// },
// }
//},
Content = new Button
{
Content = "Hello World",
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
},
};
window.Show();

Loading…
Cancel
Save