138 changed files with 1816 additions and 594 deletions
@ -0,0 +1,6 @@ |
|||
<Application xmlns="https://github.com/perspex"> |
|||
<Application.Styles> |
|||
<StyleInclude Source="resm:Perspex.Themes.Default.DefaultTheme.paml?assembly=Perspex.Themes.Default"/> |
|||
<StyleInclude Source="resm:Perspex.Themes.Default.Accents.BaseLight.paml?assembly=Perspex.Themes.Default"/> |
|||
</Application.Styles> |
|||
</Application> |
|||
@ -1,4 +1,8 @@ |
|||
<Application x:Class="XamlTestApplicationPcl.XamlTestApp" |
|||
xmlns="https://github.com/perspex" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> |
|||
<Application.Styles> |
|||
<StyleInclude Source="resm:Perspex.Themes.Default.DefaultTheme.paml?assembly=Perspex.Themes.Default"/> |
|||
<StyleInclude Source="resm:Perspex.Themes.Default.Accents.BaseLight.paml?assembly=Perspex.Themes.Default"/> |
|||
</Application.Styles> |
|||
</Application> |
|||
@ -0,0 +1,31 @@ |
|||
// 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; |
|||
|
|||
namespace Perspex.Markup.Xaml.Context |
|||
{ |
|||
public class PerspexLifeCycleListener : IInstanceLifeCycleListener |
|||
{ |
|||
public void OnAfterProperties(object instance) |
|||
{ |
|||
} |
|||
|
|||
public void OnAssociatedToParent(object instance) |
|||
{ |
|||
} |
|||
|
|||
public void OnBegin(object instance) |
|||
{ |
|||
var isi = instance as ISupportInitialize; |
|||
isi?.BeginInit(); |
|||
} |
|||
|
|||
public void OnEnd(object instance) |
|||
{ |
|||
var isi = instance as ISupportInitialize; |
|||
isi?.EndInit(); |
|||
} |
|||
} |
|||
} |
|||
@ -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 System.Globalization; |
|||
using OmniXaml.TypeConversion; |
|||
using Perspex.Media; |
|||
|
|||
namespace Perspex.Markup.Xaml.Converters |
|||
{ |
|||
public class SolidColorBrushTypeConverter : ITypeConverter |
|||
{ |
|||
public bool CanConvertFrom(IValueContext context, Type sourceType) |
|||
{ |
|||
return sourceType == typeof(string); |
|||
} |
|||
|
|||
public bool CanConvertTo(IValueContext context, Type destinationType) |
|||
{ |
|||
return false; |
|||
} |
|||
|
|||
public object ConvertFrom(IValueContext context, CultureInfo culture, object value) |
|||
{ |
|||
return Brush.Parse((string)value); |
|||
} |
|||
|
|||
public object ConvertTo(IValueContext context, CultureInfo culture, object value, Type destinationType) |
|||
{ |
|||
throw new NotImplementedException(); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,95 @@ |
|||
// 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 System.Collections.Generic; |
|||
using System.Runtime.CompilerServices; |
|||
using Perspex.Controls; |
|||
using Perspex.Data; |
|||
|
|||
namespace Perspex.Markup.Xaml.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Provides delayed bindings for controls.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// The XAML engine applies its bindings in a delayed manner where bindings are only applied
|
|||
/// when a control is added to the visual tree. This was done because applying bindings as soon
|
|||
/// as controls are created means that long-form bindings (i.e. bindings that don't use the
|
|||
/// `{Binding}` markup extension) don't work as the binding is applied to the property before
|
|||
/// the binding properties are set, and looking at WPF it uses a similar mechanism for bindings
|
|||
/// that come from XAML.
|
|||
/// </remarks>
|
|||
public static class DelayedBinding |
|||
{ |
|||
private static ConditionalWeakTable<IControl, List<Entry>> _entries = |
|||
new ConditionalWeakTable<IControl, List<Entry>>(); |
|||
|
|||
/// <summary>
|
|||
/// Adds a delayed binding to a control.
|
|||
/// </summary>
|
|||
/// <param name="target">The control.</param>
|
|||
/// <param name="property">The property on the control to bind to.</param>
|
|||
/// <param name="binding">The binding.</param>
|
|||
public static void Add(IControl target, PerspexProperty property, IBinding binding) |
|||
{ |
|||
if (target.IsAttachedToVisualTree) |
|||
{ |
|||
target.Bind(property, binding); |
|||
} |
|||
else |
|||
{ |
|||
List<Entry> bindings; |
|||
|
|||
if (!_entries.TryGetValue(target, out bindings)) |
|||
{ |
|||
bindings = new List<Entry>(); |
|||
_entries.Add(target, bindings); |
|||
|
|||
// TODO: Make this a weak event listener.
|
|||
target.AttachedToVisualTree += ApplyBindings; |
|||
} |
|||
|
|||
bindings.Add(new Entry(binding, property)); |
|||
} |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Applies any delayed bindings to a control.
|
|||
/// </summary>
|
|||
/// <param name="control">The control.</param>
|
|||
public static void ApplyBindings(IControl control) |
|||
{ |
|||
List<Entry> bindings; |
|||
|
|||
if (_entries.TryGetValue(control, out bindings)) |
|||
{ |
|||
foreach (var binding in bindings) |
|||
{ |
|||
control.Bind(binding.Property, binding.Binding); |
|||
} |
|||
|
|||
_entries.Remove(control); |
|||
} |
|||
} |
|||
|
|||
private static void ApplyBindings(object sender, VisualTreeAttachmentEventArgs e) |
|||
{ |
|||
var target = (IControl)sender; |
|||
ApplyBindings(target); |
|||
target.AttachedToVisualTree -= ApplyBindings; |
|||
} |
|||
|
|||
private class Entry |
|||
{ |
|||
public Entry(IBinding binding, PerspexProperty property) |
|||
{ |
|||
Binding = binding; |
|||
Property = property; |
|||
} |
|||
|
|||
public IBinding Binding { get; } |
|||
public PerspexProperty Property { get; } |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,65 @@ |
|||
// 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 System.Reactive.Disposables; |
|||
using System.Reactive.Linq; |
|||
using System.Reactive.Subjects; |
|||
using Perspex.Controls; |
|||
using Perspex.Data; |
|||
using Perspex.Styling; |
|||
|
|||
namespace Perspex.Markup.Xaml.Data |
|||
{ |
|||
public class StyleResourceBinding : IBinding |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="StyleResourceBinding"/> class.
|
|||
/// </summary>
|
|||
/// <param name="name">The resource name.</param>
|
|||
public StyleResourceBinding(string name) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
/// <inheritdoc/>
|
|||
public BindingMode Mode => BindingMode.OneTime; |
|||
|
|||
/// <summary>
|
|||
/// Gets the resource name.
|
|||
/// </summary>
|
|||
public string Name { get; } |
|||
|
|||
/// <inheritdoc/>
|
|||
public BindingPriority Priority => BindingPriority.LocalValue; |
|||
|
|||
/// <inheritdoc/>
|
|||
public InstancedBinding Initiate( |
|||
IPerspexObject target, |
|||
PerspexProperty targetProperty, |
|||
object anchor = null) |
|||
{ |
|||
var host = (target as IControl) ?? (anchor as IControl); |
|||
var style = anchor as IStyle; |
|||
var resource = PerspexProperty.UnsetValue; |
|||
|
|||
if (host != null) |
|||
{ |
|||
resource = host.FindStyleResource(Name); |
|||
} |
|||
else if (style != null) |
|||
{ |
|||
resource = style.FindResource(Name); |
|||
} |
|||
|
|||
if (resource != PerspexProperty.UnsetValue) |
|||
{ |
|||
return new InstancedBinding(resource, Priority); |
|||
} |
|||
else |
|||
{ |
|||
return null; |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
// 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 System.Reactive.Linq; |
|||
using OmniXaml; |
|||
using Perspex.LogicalTree; |
|||
using Perspex.Markup.Xaml.Data; |
|||
using Perspex.Styling; |
|||
|
|||
namespace Perspex.Markup.Xaml.MarkupExtensions |
|||
{ |
|||
public class StyleResourceExtension : MarkupExtension |
|||
{ |
|||
public StyleResourceExtension(string name) |
|||
{ |
|||
Name = name; |
|||
} |
|||
|
|||
public override object ProvideValue(MarkupExtensionContext extensionContext) |
|||
{ |
|||
return new StyleResourceBinding(this.Name); |
|||
} |
|||
|
|||
public string Name { get; set; } |
|||
} |
|||
} |
|||
@ -1 +1 @@ |
|||
Subproject commit 307361d65a187d404da1d4e15a553d918c3ed79c |
|||
Subproject commit 75e0dc32fe9a6d97f5b59d2b7d689db2475f444f |
|||
@ -0,0 +1,71 @@ |
|||
// 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 System.Linq; |
|||
using System.Reactive.Disposables; |
|||
using System.Reactive.Linq; |
|||
|
|||
namespace Perspex.Data |
|||
{ |
|||
public static class BindingOperations |
|||
{ |
|||
/// <summary>
|
|||
/// Applies an <see cref="InstancedBinding"/> a property on an <see cref="IPerspexObject"/>.
|
|||
/// </summary>
|
|||
/// <param name="target">The target object.</param>
|
|||
/// <param name="property">The property to bind.</param>
|
|||
/// <param name="binding">The instanced binding.</param>
|
|||
/// <param name="anchor">
|
|||
/// An optional anchor from which to locate required context. When binding to objects that
|
|||
/// are not in the logical tree, certain types of binding need an anchor into the tree in
|
|||
/// order to locate named controls or resources. The <paramref name="anchor"/> parameter
|
|||
/// can be used to provice this context.
|
|||
/// </param>
|
|||
/// <returns>An <see cref="IDisposable"/> which can be used to cancel the binding.</returns>
|
|||
public static IDisposable Apply( |
|||
IPerspexObject target, |
|||
PerspexProperty property, |
|||
InstancedBinding binding, |
|||
object anchor) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(target != null); |
|||
Contract.Requires<ArgumentNullException>(property != null); |
|||
Contract.Requires<ArgumentNullException>(binding != null); |
|||
|
|||
var mode = binding.Mode; |
|||
|
|||
if (mode == BindingMode.Default) |
|||
{ |
|||
mode = property.GetMetadata(target.GetType()).DefaultBindingMode; |
|||
} |
|||
|
|||
switch (mode) |
|||
{ |
|||
case BindingMode.Default: |
|||
case BindingMode.OneWay: |
|||
return target.Bind(property, binding.Observable ?? binding.Subject, binding.Priority); |
|||
case BindingMode.TwoWay: |
|||
return new CompositeDisposable( |
|||
target.Bind(property, binding.Subject, binding.Priority), |
|||
target.GetObservable(property).Subscribe(binding.Subject)); |
|||
case BindingMode.OneTime: |
|||
var source = binding.Subject ?? binding.Observable; |
|||
|
|||
if (source != null) |
|||
{ |
|||
return source.Take(1).Subscribe(x => target.SetValue(property, x, binding.Priority)); |
|||
} |
|||
else |
|||
{ |
|||
target.SetValue(property, binding.Value, binding.Priority); |
|||
return Disposable.Empty; |
|||
} |
|||
case BindingMode.OneWayToSource: |
|||
return target.GetObservable(property).Subscribe(binding.Subject); |
|||
default: |
|||
throw new ArgumentException("Invalid binding mode."); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,108 @@ |
|||
// 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 System.Reactive.Subjects; |
|||
|
|||
namespace Perspex.Data |
|||
{ |
|||
/// <summary>
|
|||
/// Holds the result of calling <see cref="IBinding.Initiate"/>.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// Whereas an <see cref="IBinding"/> holds a description of a binding such as "Bind to the X
|
|||
/// property on a control's DataContext"; this class represents a binding that has been
|
|||
/// *instanced* by calling <see cref="IBinding.Initiate(IPerspexObject, PerspexProperty, object)"/>
|
|||
/// on a target object.
|
|||
///
|
|||
/// When a binding is initiated, it can return one of 3 possible sources for the binding:
|
|||
/// - An <see cref="ISubject{Object}"/> which can be used for any type of binding.
|
|||
/// - An <see cref="IObservable{Object}"/> which can be used for all types of bindings except
|
|||
/// <see cref="BindingMode.OneWayToSource"/> and <see cref="BindingMode.TwoWay"/>.
|
|||
/// - A plain object, which can only represent a <see cref="BindingMode.OneTime"/> binding.
|
|||
/// </remarks>
|
|||
public class InstancedBinding |
|||
{ |
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InstancedBinding"/> class.
|
|||
/// </summary>
|
|||
/// <param name="value">
|
|||
/// The value used for the <see cref="BindingMode.OneTime"/> binding.
|
|||
/// </param>
|
|||
/// <param name="priority">The binding priority.</param>
|
|||
public InstancedBinding(object value, BindingPriority priority = BindingPriority.LocalValue) |
|||
{ |
|||
Mode = BindingMode.OneTime; |
|||
Priority = priority; |
|||
Value = value; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InstancedBinding"/> class.
|
|||
/// </summary>
|
|||
/// <param name="observable">The observable for a one-way binding.</param>
|
|||
/// <param name="mode">The binding mode.</param>
|
|||
/// <param name="priority">The binding priority.</param>
|
|||
public InstancedBinding( |
|||
IObservable<object> observable, |
|||
BindingMode mode = BindingMode.OneWay, |
|||
BindingPriority priority = BindingPriority.LocalValue) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(observable != null); |
|||
|
|||
if (mode == BindingMode.OneWayToSource || mode == BindingMode.TwoWay) |
|||
{ |
|||
throw new ArgumentException( |
|||
"Invalid BindingResult mode: OneWayToSource and TwoWay bindings" + |
|||
"require a Subject."); |
|||
} |
|||
|
|||
Mode = mode; |
|||
Priority = priority; |
|||
Observable = observable; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Initializes a new instance of the <see cref="InstancedBinding"/> class.
|
|||
/// </summary>
|
|||
/// <param name="subject">The subject for a two-way binding.</param>
|
|||
/// <param name="mode">The binding mode.</param>
|
|||
/// <param name="priority">The binding priority.</param>
|
|||
public InstancedBinding( |
|||
ISubject<object> subject, |
|||
BindingMode mode = BindingMode.OneWay, |
|||
BindingPriority priority = BindingPriority.LocalValue) |
|||
{ |
|||
Contract.Requires<ArgumentNullException>(subject != null); |
|||
|
|||
Mode = mode; |
|||
Priority = priority; |
|||
Subject = subject; |
|||
} |
|||
|
|||
/// <summary>
|
|||
/// Gets the binding mode with which the binding was initiated.
|
|||
/// </summary>
|
|||
public BindingMode Mode { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the binding priority.
|
|||
/// </summary>
|
|||
public BindingPriority Priority { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the value used for a <see cref="BindingMode.OneTime"/> binding.
|
|||
/// </summary>
|
|||
public object Value { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the observable for a one-way binding.
|
|||
/// </summary>
|
|||
public IObservable<object> Observable { get; } |
|||
|
|||
/// <summary>
|
|||
/// Gets the subject for a two-way binding.
|
|||
/// </summary>
|
|||
public ISubject<object> Subject { get; } |
|||
} |
|||
} |
|||
@ -0,0 +1,22 @@ |
|||
// 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.
|
|||
|
|||
namespace Perspex |
|||
{ |
|||
/// <summary>
|
|||
/// Specifies that this object supports a simple, transacted notification for batch
|
|||
/// initialization.
|
|||
/// </summary>
|
|||
public interface ISupportInitialize |
|||
{ |
|||
/// <summary>
|
|||
/// Signals the object that initialization is starting.
|
|||
/// </summary>
|
|||
void BeginInit(); |
|||
|
|||
/// <summary>
|
|||
/// Signals the object that initialization is complete.
|
|||
/// </summary>
|
|||
void EndInit(); |
|||
} |
|||
} |
|||
@ -0,0 +1,35 @@ |
|||
// 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.
|
|||
|
|||
namespace Perspex.Media.Mutable |
|||
{ |
|||
/// <summary>
|
|||
/// Fills an area with a solid color.
|
|||
/// </summary>
|
|||
/// <remarks>
|
|||
/// This is a mutable version of the normal immutable <see cref="Perspex.Media.SolidColorBrush"/>
|
|||
/// for use in XAML. XAML really needs support for immutable data...
|
|||
/// </remarks>
|
|||
public class SolidColorBrush : Brush |
|||
{ |
|||
public static readonly DirectProperty<SolidColorBrush, Color> ColorProperty = |
|||
PerspexProperty.RegisterDirect<SolidColorBrush, Color>( |
|||
"Color", |
|||
o => o.Color, |
|||
(o, v) => o.Color = v); |
|||
|
|||
/// <summary>
|
|||
/// Gets the color of the brush.
|
|||
/// </summary>
|
|||
public Color Color { get; set; } |
|||
|
|||
/// <summary>
|
|||
/// Returns a string representation of the brush.
|
|||
/// </summary>
|
|||
/// <returns>A string representation of the brush.</returns>
|
|||
public override string ToString() |
|||
{ |
|||
return Color.ToString(); |
|||
} |
|||
} |
|||
} |
|||
@ -1,15 +1,26 @@ |
|||
// 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 Perspex.Collections; |
|||
|
|||
namespace Perspex |
|||
namespace Perspex.LogicalTree |
|||
{ |
|||
/// <summary>
|
|||
/// Represents a node in the logical tree.
|
|||
/// </summary>
|
|||
public interface ILogical |
|||
{ |
|||
/// <summary>
|
|||
/// Raised when the control is attached to a rooted logical tree.
|
|||
/// </summary>
|
|||
event EventHandler<LogicalTreeAttachmentEventArgs> AttachedToLogicalTree; |
|||
|
|||
/// <summary>
|
|||
/// Raised when the control is detached from a rooted logical tree.
|
|||
/// </summary>
|
|||
event EventHandler<LogicalTreeAttachmentEventArgs> DetachedFromLogicalTree; |
|||
|
|||
/// <summary>
|
|||
/// Gets a value indicating whether the element is attached to a rooted logical tree.
|
|||
/// </summary>
|
|||
@ -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; |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,29 @@ |
|||
<Style xmlns="https://github.com/perspex" |
|||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" |
|||
xmlns:mut="https://github.com/perspex/mutable" |
|||
xmlns:sys="clr-namespace:System;assembly=mscorlib"> |
|||
<Style.Resources> |
|||
<SolidColorBrush x:Key="ThemeBackgroundBrush">#FFFFFFFF</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeBorderLightBrush">#FFAAAAAA</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeBorderMidBrush">#FF888888</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeBorderDarkBrush">#FF333333</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeControlLightBrush">#FFFFFFFF</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeControlMidBrush">#FFAAAAAA</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeControlDarkBrush">#FF888888</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeForegroundBrush">#FF000000</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeForegroundLightBrush">#FF808080</SolidColorBrush> |
|||
|
|||
<SolidColorBrush x:Key="HighlightBrush">#FF086F9E</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeAccentBrush">#CC119EDA</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeAccentBrush2">#99119EDA</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeAccentBrush3">#66119EDA</SolidColorBrush> |
|||
<SolidColorBrush x:Key="ThemeAccentBrush4">#33119EDA</SolidColorBrush> |
|||
|
|||
<sys:Double x:Key="ThemeBorderThickness">2</sys:Double> |
|||
<sys:Double x:Key="ThemeDisabledOpacity">0.5</sys:Double> |
|||
|
|||
<sys:Double x:Key="FontSizeSmall">10</sys:Double> |
|||
<sys:Double x:Key="FontSizeNormal">12</sys:Double> |
|||
<sys:Double x:Key="FontSizeLarge">16</sys:Double> |
|||
</Style.Resources> |
|||
</Style> |
|||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue