Browse Source

More work on XAML styles.

- Added "Control[Property=Value]" selector handling
- Added hacks for ExpressionObserver not currently handing attached
properties
- Added ContentControl style
- Fixed ScrollBar and TextBox
pull/297/head
Steven Kirk 11 years ago
parent
commit
142eaa1c7c
  1. 9
      samples/XamlTestApplicationPcl/ContentControl.paml
  2. 14
      samples/XamlTestApplicationPcl/ScrollBar.paml
  3. 3
      samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj
  4. 32
      src/Markup/Perspex.Markup.Xaml/Parsers/SelectorParser.cs
  5. 15
      src/Perspex.Base/Utilities/TypeUtilities.cs
  6. 7
      src/Perspex.Controls/ContentControl.cs
  7. 42
      src/Perspex.Controls/ScrollViewer.cs
  8. 21
      src/Perspex.Controls/TextBox.cs
  9. 18
      src/Perspex.Styling/Styling/Selectors.cs

9
samples/XamlTestApplicationPcl/ContentControl.paml

@ -0,0 +1,9 @@
<Style xmlns="https://github.com/perspex" Selector="ContentControl">
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}">
<ContentPresenter Content="{TemplateBinding Content}" Margin="{TemplateBinding Padding}"/>
</Border>
</ControlTemplate>
</Setter>
</Style>

14
samples/XamlTestApplicationPcl/ScrollBar.paml

@ -8,7 +8,7 @@
Value="{TemplateBinding Path=Value, Mode=TwoWay}"
ViewportSize="{TemplateBinding ViewportSize}"
Orientation="{TemplateBinding Orientation}">
<Thumb>
<Thumb Name="thumb">
<Thumb.Template>
<ControlTemplate>
<Border Background="Gray"/>
@ -20,4 +20,16 @@
</ControlTemplate>
</Setter>
</Style>
<Style Selector="ScrollBar[Orientation=Horizontal]">
<Setter Property="Height" Value="10"/>
</Style>
<Style Selector="ScrollBar[Orientation=Horizontal] /template/ Thumb#thumb">
<Setter Property="MinWidth" Value="10"/>
</Style>
<Style Selector="ScrollBar[Orientation=Vertical]">
<Setter Property="Width" Value="10"/>
</Style>
<Style Selector="ScrollBar[Orientation=Vertical] /template/ Thumb#thumb">
<Setter Property="MinHeight" Value="10"/>
</Style>
</Styles>

3
samples/XamlTestApplicationPcl/XamlTestApplicationPcl.csproj

@ -164,6 +164,9 @@
<EmbeddedResource Include="TextBox.paml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="ContentControl.paml">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.

32
src/Markup/Perspex.Markup.Xaml/Parsers/SelectorParser.cs

@ -2,7 +2,9 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
using System.Globalization;
using Perspex.Styling;
using Perspex.Utilities;
using Sprache;
namespace Perspex.Markup.Xaml.Parsers
@ -61,7 +63,35 @@ namespace Perspex.Markup.Xaml.Parsers
}
else if (property != null)
{
throw new NotImplementedException();
var type = result.TargetType;
if (type == null)
{
throw new InvalidOperationException("Property selectors must be applied to a type.");
}
var targetProperty = PerspexPropertyRegistry.Instance.FindRegistered(type, property.Property);
if (targetProperty == null)
{
throw new InvalidOperationException($"Cannot find '{property.Property}' on '{type}");
}
object typedValue;
if (TypeUtilities.TryConvert(
targetProperty.PropertyType,
property.Value,
CultureInfo.InvariantCulture,
out typedValue))
{
result = result.PropertyEquals(targetProperty, typedValue);
}
else
{
throw new InvalidOperationException(
$"Could not convert '{property.Value}' to '{targetProperty.PropertyType}");
}
}
else if (child != null)
{

15
src/Perspex.Base/Utilities/TypeUtilities.cs

@ -91,7 +91,7 @@ namespace Perspex.Utilities
/// <summary>
/// Try to convert a value to a type, using <see cref="System.Convert"/> if possible,
/// otherwise using <see cref="TryCast(Type, object, out object, bool)"/>.
/// otherwise using <see cref="TryCast(Type, object, out object)"/>.
/// </summary>
/// <param name="to">The type to cast to.</param>
/// <param name="value">The value to cast.</param>
@ -100,7 +100,18 @@ namespace Perspex.Utilities
/// <returns>True if the cast was sucessful, otherwise false.</returns>
public static bool TryConvert(Type to, object value, CultureInfo culture, out object result)
{
if ((value.GetType() == typeof(string) && Conversions.ContainsKey(to)) ||
var valueType = value.GetType();
if (to.GetTypeInfo().IsEnum && valueType == typeof(string))
{
if (Enum.IsDefined(to, (string)value))
{
result = Enum.Parse(to, (string)value);
return true;
}
}
if ((valueType == typeof(string) && Conversions.ContainsKey(to)) ||
(to == typeof(string) && Conversions.ContainsKey(value.GetType())))
{
try

7
src/Perspex.Controls/ContentControl.cs

@ -34,6 +34,13 @@ namespace Perspex.Controls
public static readonly PerspexProperty<VerticalAlignment> VerticalContentAlignmentProperty =
PerspexProperty.Register<ContentControl, VerticalAlignment>(nameof(VerticalContentAlignment));
/// <summary>
/// Initializes static members of the <see cref="Button"/> class.
/// </summary>
static ContentControl()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="ContentControl"/> class.
/// </summary>

42
src/Perspex.Controls/ScrollViewer.cs

@ -112,12 +112,54 @@ namespace Perspex.Controls
set { SetValue(CanScrollHorizontallyProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public double HorizontalScrollBarMaximum
{
get { return GetValue(HorizontalScrollBarMaximumProperty); }
private set { SetValue(HorizontalScrollBarMaximumProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public double HorizontalScrollBarValue
{
get { return GetValue(HorizontalScrollBarValueProperty); }
private set { SetValue(HorizontalScrollBarValueProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public double HorizontalScrollBarViewportSize
{
get { return GetValue(HorizontalScrollBarViewportSizeProperty); }
set { SetValue(HorizontalScrollBarViewportSizeProperty, value); }
}
public ScrollBarVisibility HorizontalScrollBarVisibility
{
get { return GetValue(HorizontalScrollBarVisibilityProperty); }
set { SetValue(HorizontalScrollBarVisibilityProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public double VerticalScrollBarMaximum
{
get { return GetValue(VerticalScrollBarMaximumProperty); }
private set { SetValue(VerticalScrollBarMaximumProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public double VerticalScrollBarValue
{
get { return GetValue(VerticalScrollBarValueProperty); }
private set { SetValue(VerticalScrollBarValueProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public double VerticalScrollBarViewportSize
{
get { return GetValue(VerticalScrollBarViewportSizeProperty); }
private set { SetValue(VerticalScrollBarViewportSizeProperty, value); }
}
public ScrollBarVisibility VerticalScrollBarVisibility
{
get { return GetValue(VerticalScrollBarVisibilityProperty); }

21
src/Perspex.Controls/TextBox.cs

@ -127,6 +127,27 @@ namespace Perspex.Controls
set { SetValue(TextWrappingProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public bool CanScrollHorizontally
{
get { return GetValue(ScrollViewer.CanScrollHorizontallyProperty); }
set { SetValue(ScrollViewer.CanScrollHorizontallyProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public ScrollBarVisibility HorizontalScrollBarVisibility
{
get { return GetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty); }
set { SetValue(ScrollViewer.HorizontalScrollBarVisibilityProperty, value); }
}
// HACK: Currently exposed because XAML bindings don't work with attached perspex properties.
public ScrollBarVisibility VerticalScrollBarVisibility
{
get { return GetValue(ScrollViewer.VerticalScrollBarVisibilityProperty); }
set { SetValue(ScrollViewer.VerticalScrollBarVisibilityProperty, value); }
}
protected override void OnTemplateApplied()
{
_presenter = this.GetTemplateChild<TextPresenter>("PART_TextPresenter");

18
src/Perspex.Styling/Styling/Selectors.cs

@ -128,6 +128,22 @@ namespace Perspex.Styling
return new Selector(previous, x => MatchPropertyEquals(x, property, value), $"[{property.Name}={value}]");
}
/// <summary>
/// Returns a selector which matches a control with the specified property value.
/// </summary>
/// <typeparam name="T">The property type.</typeparam>
/// <param name="previous">The previous selector.</param>
/// <param name="property">The property.</param>
/// <param name="value">The property value.</param>
/// <returns>The selector.</returns>
public static Selector PropertyEquals(this Selector previous, PerspexProperty property, object value)
{
Contract.Requires<ArgumentNullException>(previous != null);
Contract.Requires<ArgumentNullException>(property != null);
return new Selector(previous, x => MatchPropertyEquals(x, property, value), $"[{property.Name}={value}]");
}
/// <summary>
/// Returns a selector which enters a lookless control's template.
/// </summary>
@ -216,7 +232,7 @@ namespace Perspex.Styling
return new SelectorMatch(controlType == type);
}
private static SelectorMatch MatchPropertyEquals<T>(IStyleable x, PerspexProperty<T> property, object value)
private static SelectorMatch MatchPropertyEquals(IStyleable x, PerspexProperty property, object value)
{
if (!x.IsRegistered(property))
{

Loading…
Cancel
Save