Browse Source

Started adding StyleResource markup extension.

OmniXAML issue #84 is now blocking us.
pull/464/head
Steven Kirk 11 years ago
parent
commit
19af37a6af
  1. 33
      src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs
  2. 2
      src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj
  3. 12
      src/Markup/Perspex.Markup.Xaml/Styling/StyleInclude.cs
  4. 1
      src/Perspex.Styling/Perspex.Styling.csproj
  5. 9
      src/Perspex.Styling/Styling/IStyle.cs
  6. 49
      src/Perspex.Styling/Styling/Style.cs
  7. 39
      src/Perspex.Styling/Styling/StyleExtensions.cs
  8. 23
      src/Perspex.Styling/Styling/Styles.cs
  9. 27
      tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs
  10. 1
      tests/Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj
  11. 78
      tests/Perspex.Styling.UnitTests/ResourceTests.cs

33
src/Markup/Perspex.Markup.Xaml/MarkupExtensions/StyleResourceExtension.cs

@ -0,0 +1,33 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using OmniXaml;
using Perspex.LogicalTree;
using Perspex.Styling;
namespace Perspex.Markup.Xaml.MarkupExtensions
{
public class StyleResourceExtension : MarkupExtension
{
public StyleResourceExtension(string name)
{
Name = name;
}
public override object ProvideValue(MarkupExtensionContext extensionContext)
{
var styleHost = extensionContext.TargetObject as IStyleHost;
if (styleHost == null)
{
throw new ParseException(
$"StyleResource cannot be assigned to an object of type '{styleHost.GetType()}'.");
}
return styleHost.FindStyleResource(Name);
}
public string Name { get; set; }
}
}

2
src/Markup/Perspex.Markup.Xaml/Perspex.Markup.Xaml.csproj

@ -55,6 +55,7 @@
<Compile Include="Converters\BitmapTypeConverter.cs" />
<Compile Include="Converters\BrushTypeConverter.cs" />
<Compile Include="Converters\ClassesTypeConverter.cs" />
<Compile Include="Converters\SolidColorBrushTypeConverter.cs" />
<Compile Include="Converters\ColorTypeConverter.cs" />
<Compile Include="Converters\ColumnDefinitionsTypeConverter.cs" />
<Compile Include="Converters\CursorTypeConverter.cs" />
@ -78,6 +79,7 @@
<Compile Include="Data\RelativeSource.cs" />
<Compile Include="Data\SourceBindingEndpoint.cs" />
<Compile Include="Data\TargetBindingEndpoint.cs" />
<Compile Include="MarkupExtensions\StyleResourceExtension.cs" />
<Compile Include="MarkupExtensions\BindingExtension.cs" />
<Compile Include="MarkupExtensions\RelativeSourceExtension.cs" />
<Compile Include="MarkupExtensions\StaticExtension.cs" />

12
src/Markup/Perspex.Markup.Xaml/Styling/StyleInclude.cs

@ -35,5 +35,17 @@ namespace Perspex.Markup.Xaml.Styling
Loaded.Attach(control, container);
}
}
/// <summary>
/// Tries to find a named resource within the style.
/// </summary>
/// <param name="name">The resource name.</param>
/// <returns>
/// The resource if found, otherwise <see cref="PerspexProperty.UnsetValue"/>.
/// </returns>
public object FindResource(string name)
{
return Loaded.FindResource(name);
}
}
}

1
src/Perspex.Styling/Perspex.Styling.csproj

@ -63,6 +63,7 @@
<Compile Include="Styling\Style.cs" />
<Compile Include="Styling\StyleActivator.cs" />
<Compile Include="Styling\ActivatedObservable.cs" />
<Compile Include="Styling\StyleExtensions.cs" />
<Compile Include="Styling\Styler.cs" />
<Compile Include="Styling\Styles.cs" />
</ItemGroup>

9
src/Perspex.Styling/Styling/IStyle.cs

@ -16,5 +16,14 @@ namespace Perspex.Styling
/// The control that contains this style. May be null.
/// </param>
void Attach(IStyleable control, IStyleHost container);
/// <summary>
/// Tries to find a named resource within the style.
/// </summary>
/// <param name="name">The resource name.</param>
/// <returns>
/// The resource if found, otherwise <see cref="PerspexProperty.UnsetValue"/>.
/// </returns>
object FindResource(string name);
}
}

49
src/Perspex.Styling/Styling/Style.cs

@ -14,14 +14,13 @@ namespace Perspex.Styling
public class Style : IStyle
{
private static readonly IObservable<bool> True = Observable.Never<bool>().StartWith(true);
private Lazy<Dictionary<string, object>> _resources;
private Dictionary<string, object> _resources;
/// <summary>
/// Initializes a new instance of the <see cref="Style"/> class.
/// </summary>
public Style()
{
_resources = new Lazy<Dictionary<string, object>>(() => new Dictionary<string, object>());
}
/// <summary>
@ -34,9 +33,30 @@ namespace Perspex.Styling
}
/// <summary>
/// Gets a dictionary of style resources.
/// Gets or sets a dictionary of style resources.
/// </summary>
public IDictionary<string, object> Resources => _resources.Value;
public IDictionary<string, object> Resources
{
get
{
if (_resources == null)
{
_resources = new Dictionary<string, object>();
}
return _resources;
}
set
{
var resources = Resources;
foreach (var i in value)
{
resources.Add(i);
}
}
}
/// <summary>
/// Gets or sets style's selector.
@ -83,6 +103,27 @@ namespace Perspex.Styling
}
}
/// <summary>
/// Tries to find a named resource within the style.
/// </summary>
/// <param name="name">The resource name.</param>
/// <returns>
/// The resource if found, otherwise <see cref="PerspexProperty.UnsetValue"/>.
/// </returns>
public object FindResource(string name)
{
object result = null;
if (_resources?.TryGetValue(name, out result) == true)
{
return result;
}
else
{
return PerspexProperty.UnsetValue;
}
}
/// <summary>
/// Returns a string representation of the style.
/// </summary>

39
src/Perspex.Styling/Styling/StyleExtensions.cs

@ -0,0 +1,39 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
namespace Perspex.Styling
{
public static class StyleExtensions
{
/// <summary>
/// Tries to find a named style resource.
/// </summary>
/// <param name="control">The control from which to find the resource.</param>
/// <param name="name">The resource name.</param>
/// <returns>
/// The resource if found, otherwise <see cref="PerspexProperty.UnsetValue"/>.
/// </returns>
public static object FindStyleResource(this IStyleHost control, string name)
{
Contract.Requires<ArgumentNullException>(control != null);
Contract.Requires<ArgumentNullException>(name != null);
Contract.Requires<ArgumentException>(!string.IsNullOrWhiteSpace(name));
while (control != null)
{
var result = control.Styles.FindResource(name);
if (result != PerspexProperty.UnsetValue)
{
return result;
}
control = control.StylingParent;
}
return PerspexProperty.UnsetValue;
}
}
}

23
src/Perspex.Styling/Styling/Styles.cs

@ -1,6 +1,7 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Linq;
using Perspex.Collections;
namespace Perspex.Styling
@ -24,5 +25,27 @@ namespace Perspex.Styling
style.Attach(control, container);
}
}
/// <summary>
/// Tries to find a named resource within the style.
/// </summary>
/// <param name="name">The resource name.</param>
/// <returns>
/// The resource if found, otherwise <see cref="PerspexProperty.UnsetValue"/>.
/// </returns>
public object FindResource(string name)
{
foreach (var style in this.Reverse())
{
var result = style.FindResource(name);
if (result != PerspexProperty.UnsetValue)
{
return result;
}
}
return PerspexProperty.UnsetValue;
}
}
}

27
tests/Perspex.Markup.Xaml.UnitTests/StyleTests.cs

@ -19,7 +19,7 @@ namespace Perspex.Markup.Xaml.UnitTests
public void Color_Can_Be_Added_To_Style_Resources()
{
using (UnitTestApplication.Start(TestServices.MockPlatformWrapper))
{
{
var xaml = @"
<UserControl xmlns='https://github.com/perspex'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
@ -63,6 +63,31 @@ namespace Perspex.Markup.Xaml.UnitTests
}
}
[Fact]
public void StyleResource_Can_Be_Assigned_To_Property()
{
var xaml = @"
<UserControl xmlns='https://github.com/perspex'
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'>
<UserControl.Styles>
<Style>
<Style.Resources>
<SolidColorBrush x:Key='brush'>#ff506070</SolidColorBrush>
</Style.Resources>
</Style>
</UserControl.Styles>
<Border Name='border' Background='{StyleResource brush}'/>
</UserControl>";
var loader = new PerspexXamlLoader();
var userControl = (UserControl)loader.Load(xaml);
var border = userControl.FindControl<Border>("border");
var brush = (SolidColorBrush)border.Background;
Assert.Equal(0xff506070, brush.Color.ToUint32());
}
[Fact]
public void Binding_Should_Be_Assigned_To_Setter_Value_Instead_Of_Bound()
{

1
tests/Perspex.Styling.UnitTests/Perspex.Styling.UnitTests.csproj

@ -97,6 +97,7 @@
<Compile Include="SelectorTests_PropertyEquals.cs" />
<Compile Include="SelectorTests_OfType.cs" />
<Compile Include="SelectorTests_Template.cs" />
<Compile Include="ResourceTests.cs" />
<Compile Include="StyleActivatorTests.cs" />
<Compile Include="ActivatedObservableTests.cs" />
<Compile Include="SetterTests.cs" />

78
tests/Perspex.Styling.UnitTests/ResourceTests.cs

@ -0,0 +1,78 @@
// Copyright (c) The Perspex Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System.Collections.Generic;
using Perspex.Controls;
using Xunit;
namespace Perspex.Styling.UnitTests
{
public class ResourceTests
{
[Fact]
public void FindStyleResource_Should_Find_Correct_Resource()
{
Border target;
var tree = new Decorator
{
Styles = new Styles
{
new Style
{
Resources = new Dictionary<string, object>
{
{ "Foo", "foo resource" },
{ "Bar", "overridden" },
}
}
},
Child = target = new Border
{
Styles = new Styles
{
new Style
{
Resources = new Dictionary<string, object>
{
{ "Bar", "again overridden" },
}
},
new Style
{
Resources = new Dictionary<string, object>
{
{ "Bar", "bar resource" },
}
}
}
}
};
Assert.Equal("foo resource", target.FindStyleResource("Foo"));
Assert.Equal("bar resource", target.FindStyleResource("Bar"));
}
[Fact]
public void FindStyleResource_Should_Return_UnsetValue_For_Not_Found()
{
Border target;
var tree = target = new Border
{
Styles = new Styles
{
new Style
{
Resources = new Dictionary<string, object>
{
{ "Foo", "foo" },
}
},
}
};
Assert.Equal(PerspexProperty.UnsetValue, target.FindStyleResource("Baz"));
}
}
}
Loading…
Cancel
Save