diff --git a/.gitmodules b/.gitmodules
index 22a241f120..10c780c09f 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,6 +1,3 @@
-[submodule "src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github"]
- path = src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github
- url = https://github.com/AvaloniaUI/Portable.Xaml.git
[submodule "nukebuild/Numerge"]
path = nukebuild/Numerge
url = https://github.com/kekekeks/Numerge.git
diff --git a/samples/ControlCatalog/Pages/TextBoxPage.xaml b/samples/ControlCatalog/Pages/TextBoxPage.xaml
index 49f2eea636..64118a00b4 100644
--- a/samples/ControlCatalog/Pages/TextBoxPage.xaml
+++ b/samples/ControlCatalog/Pages/TextBoxPage.xaml
@@ -26,9 +26,10 @@
-
+
diff --git a/src/Avalonia.Build.Tasks/Program.cs b/src/Avalonia.Build.Tasks/Program.cs
index c2d0950264..d356b15408 100644
--- a/src/Avalonia.Build.Tasks/Program.cs
+++ b/src/Avalonia.Build.Tasks/Program.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.IO;
+using System.Linq;
using Microsoft.Build.Framework;
namespace Avalonia.Build.Tasks
@@ -11,8 +12,14 @@ namespace Avalonia.Build.Tasks
{
if (args.Length != 3)
{
- Console.Error.WriteLine("input references output");
- return 1;
+ if (args.Length == 1)
+ args = new[] {"original.dll", "references", "out.dll"}
+ .Select(x => Path.Combine(args[0], x)).ToArray();
+ else
+ {
+ Console.Error.WriteLine("input references output");
+ return 1;
+ }
}
return new CompileAvaloniaXamlTask()
diff --git a/src/Avalonia.Controls/ColumnDefinitions.cs b/src/Avalonia.Controls/ColumnDefinitions.cs
index 4f5bbf3bc3..d4fc2ee0a1 100644
--- a/src/Avalonia.Controls/ColumnDefinitions.cs
+++ b/src/Avalonia.Controls/ColumnDefinitions.cs
@@ -16,10 +16,8 @@ namespace Avalonia.Controls
///
/// Initializes a new instance of the class.
///
- public ColumnDefinitions()
+ public ColumnDefinitions() : base ()
{
- ResetBehavior = ResetBehavior.Remove;
- CollectionChanged += OnCollectionChanged;
}
///
diff --git a/src/Avalonia.Controls/DefinitionBase.cs b/src/Avalonia.Controls/DefinitionBase.cs
index 8899c38bf9..a68fe1265f 100644
--- a/src/Avalonia.Controls/DefinitionBase.cs
+++ b/src/Avalonia.Controls/DefinitionBase.cs
@@ -20,49 +20,15 @@ namespace Avalonia.Controls
///
public abstract class DefinitionBase : AvaloniaObject
{
- //------------------------------------------------------
- //
- // Constructors
- //
- //------------------------------------------------------
-
- #region Constructors
-
- /* internal DefinitionBase(bool isColumnDefinition)
- {
- _isColumnDefinition = isColumnDefinition;
- _parentIndex = -1;
- }*/
-
- #endregion Constructors
-
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
-
- #region Public Properties
-
///
/// SharedSizeGroup property.
///
public string SharedSizeGroup
{
- get { return (string) GetValue(SharedSizeGroupProperty); }
+ get { return (string)GetValue(SharedSizeGroupProperty); }
set { SetValue(SharedSizeGroupProperty, value); }
}
- #endregion Public Properties
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
-
- #region Internal Methods
-
///
/// Callback to notify about entering model tree.
///
@@ -86,15 +52,6 @@ namespace Avalonia.Controls
}
}
- protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e)
- {
- if (e.Property.PropertyType == typeof(GridLength)
- || e.Property.PropertyType == typeof(double))
- OnUserSizePropertyChanged(e);
-
- base.OnPropertyChanged(e);
- }
-
///
/// Callback to notify about exitting model tree.
///
@@ -139,119 +96,14 @@ namespace Avalonia.Controls
_minSize = minSize;
}
- ///
- ///
- ///
- ///
- /// This method needs to be internal to be accessable from derived classes.
- ///
- internal void OnUserSizePropertyChanged(AvaloniaPropertyChangedEventArgs e)
- {
- if (InParentLogicalTree)
- {
- if (_sharedState != null)
- {
- _sharedState.Invalidate();
- }
- else
- {
- if (((GridLength)e.OldValue).GridUnitType != ((GridLength)e.NewValue).GridUnitType)
- {
- Parent.Invalidate();
- }
- else
- {
- Parent.InvalidateMeasure();
- }
- }
- }
- }
- ///
- ///
- ///
- ///
- /// This method needs to be internal to be accessable from derived classes.
- ///
- internal static bool IsUserSizePropertyValueValid(object value)
- {
- return (((GridLength)value).Value >= 0);
- }
-
- ///
- ///
- ///
- ///
- /// This method needs to be internal to be accessable from derived classes.
- ///
- internal static void OnUserMinSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
- {
- DefinitionBase definition = (DefinitionBase) d;
-
- if (definition.InParentLogicalTree)
- {
- Grid parentGrid = (Grid) definition.Parent;
- parentGrid.InvalidateMeasure();
- }
- }
-
- ///
- ///
- ///
- ///
- /// This method needs to be internal to be accessable from derived classes.
- ///
- internal static bool IsUserMinSizePropertyValueValid(object value)
- {
- double v = (double)value;
- return (!double.IsNaN(v) && v >= 0.0d && !Double.IsPositiveInfinity(v));
- }
-
- ///
- ///
- ///
- ///
- /// This method needs to be internal to be accessable from derived classes.
- ///
- internal static void OnUserMaxSizePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
- {
- DefinitionBase definition = (DefinitionBase) d;
-
- if (definition.InParentLogicalTree)
- {
- Grid parentGrid = (Grid) definition.Parent;
- parentGrid.InvalidateMeasure();
- }
- }
-
- ///
- ///
- ///
- ///
- /// This method needs to be internal to be accessable from derived classes.
- ///
- internal static bool IsUserMaxSizePropertyValueValid(object value)
- {
- double v = (double)value;
- return (!double.IsNaN(v) && v >= 0.0d);
- }
-
- ///
- ///
- ///
///
/// This method reflects Grid.SharedScopeProperty state by setting / clearing
/// dynamic property PrivateSharedSizeScopeProperty. Value of PrivateSharedSizeScopeProperty
/// is a collection of SharedSizeState objects for the scope.
- /// Also PrivateSharedSizeScopeProperty is FrameworkPropertyMetadataOptions.Inherits property. So that all children
- /// elements belonging to a certain scope can easily access SharedSizeState collection. As well
- /// as been norified about enter / exit a scope.
///
internal static void OnIsSharedSizeScopePropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
{
- // is it possible to optimize here something like this:
- // if ((bool)d.GetValue(Grid.IsSharedSizeScopeProperty) == (d.GetLocalValue(PrivateSharedSizeScopeProperty) != null)
- // { /* do nothing */ }
- if ((bool) e.NewValue)
+ if ((bool)e.NewValue)
{
SharedSizeScope sharedStatesCollection = new SharedSizeScope();
d.SetValue(PrivateSharedSizeScopeProperty, sharedStatesCollection);
@@ -262,16 +114,6 @@ namespace Avalonia.Controls
}
}
- #endregion Internal Methods
-
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
-
- #region Internal Properties
-
///
/// Returns true if this definition is a part of shared group.
///
@@ -349,8 +191,8 @@ namespace Avalonia.Controls
get
{
double preferredSize = MinSize;
- if ( _sizeType != Grid.LayoutTimeSizeType.Auto
- && preferredSize < _measureSize )
+ if (_sizeType != Grid.LayoutTimeSizeType.Auto
+ && preferredSize < _measureSize)
{
preferredSize = _measureSize;
}
@@ -375,9 +217,9 @@ namespace Avalonia.Controls
get
{
double minSize = _minSize;
- if ( UseSharedMinimum
- && _sharedState != null
- && minSize < _sharedState.MinSize )
+ if (UseSharedMinimum
+ && _sharedState != null
+ && minSize < _sharedState.MinSize)
{
minSize = _sharedState.MinSize;
}
@@ -393,9 +235,9 @@ namespace Avalonia.Controls
get
{
double minSize = _minSize;
- if ( _sharedState != null
- && (UseSharedMinimum || !LayoutWasUpdated)
- && minSize < _sharedState.MinSize )
+ if (_sharedState != null
+ && (UseSharedMinimum || !LayoutWasUpdated)
+ && minSize < _sharedState.MinSize)
{
minSize = _sharedState.MinSize;
}
@@ -426,27 +268,9 @@ namespace Avalonia.Controls
/// Internal helper to access up-to-date UserMaxSize property value.
///
internal abstract double UserMaxSizeValueCache { get; }
-
- ///
- /// Protected. Returns true if this DefinitionBase instance is in parent's logical tree.
- ///
- internal bool InParentLogicalTree
- {
- get { return (_parentIndex != -1); }
- }
internal Grid Parent { get; set; }
- #endregion Internal Properties
-
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
- #region Private Methods
-
///
/// SetFlags is used to set or unset one or multiple
/// flags on the object.
@@ -465,16 +289,13 @@ namespace Avalonia.Controls
return ((_flags & flags) == flags);
}
- ///
- ///
- ///
private static void OnSharedSizeGroupPropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
{
- DefinitionBase definition = (DefinitionBase) d;
-
- if (definition.InParentLogicalTree)
+ DefinitionBase definition = (DefinitionBase)d;
+
+ if (definition.Parent != null)
{
- string sharedSizeGroupId = (string) e.NewValue;
+ string sharedSizeGroupId = (string)e.NewValue;
if (definition._sharedState != null)
{
@@ -483,7 +304,7 @@ namespace Avalonia.Controls
definition._sharedState.RemoveMember(definition);
definition._sharedState = null;
}
-
+
if ((definition._sharedState == null) && (sharedSizeGroupId != null))
{
SharedSizeScope privateSharedSizeScope = definition.PrivateSharedSizeScope;
@@ -498,9 +319,6 @@ namespace Avalonia.Controls
}
}
- ///
- ///
- ///
///
/// Verifies that Shared Size Group Property string
/// a) not empty.
@@ -520,10 +338,10 @@ namespace Avalonia.Controls
{
bool isDigit = Char.IsDigit(id[i]);
- if ( (i == 0 && isDigit)
- || !( isDigit
- || Char.IsLetter(id[i])
- || '_' == id[i] ) )
+ if ((i == 0 && isDigit)
+ || !(isDigit
+ || Char.IsLetter(id[i])
+ || '_' == id[i]))
{
break;
}
@@ -535,12 +353,9 @@ namespace Avalonia.Controls
}
}
- throw new ArgumentException("Invalid SharedSizeGroup string.");
+ throw new ArgumentException("Invalid SharedSizeGroup string.");
}
- ///
- ///
- ///
///
/// OnPrivateSharedSizeScopePropertyChanged is called when new scope enters or
/// existing scope just left. In both cases if the DefinitionBase object is already registered
@@ -550,9 +365,9 @@ namespace Avalonia.Controls
{
DefinitionBase definition = (DefinitionBase)d;
- if (definition.InParentLogicalTree)
+ if (definition.Parent != null)
{
- SharedSizeScope privateSharedSizeScope = (SharedSizeScope) e.NewValue;
+ SharedSizeScope privateSharedSizeScope = (SharedSizeScope)e.NewValue;
if (definition._sharedState != null)
{
@@ -576,22 +391,12 @@ namespace Avalonia.Controls
}
}
- #endregion Private Methods
-
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
-
- #region Private Properties
-
///
/// Private getter of shared state collection dynamic property.
///
private SharedSizeScope PrivateSharedSizeScope
{
- get { return (SharedSizeScope) GetValue(PrivateSharedSizeScopeProperty); }
+ get { return (SharedSizeScope)GetValue(PrivateSharedSizeScopeProperty); }
}
///
@@ -612,16 +417,6 @@ namespace Avalonia.Controls
set { SetFlags(value, Flags.LayoutWasUpdated); }
}
- #endregion Private Properties
-
- //------------------------------------------------------
- //
- // Private Fields
- //
- //------------------------------------------------------
-
- #region Private Fields
- private readonly bool _isColumnDefinition; // when "true", this is a ColumnDefinition; when "false" this is a RowDefinition (faster than a type check)
private Flags _flags; // flags reflecting various aspects of internal state
internal int _parentIndex = -1; // this instance's index in parent's children collection
@@ -633,19 +428,6 @@ namespace Avalonia.Controls
private double _offset; // offset of the DefinitionBase from left / top corner (assuming LTR case)
private SharedSizeState _sharedState; // reference to shared state object this instance is registered with
-
- internal const bool ThisIsColumnDefinition = true;
- internal const bool ThisIsRowDefinition = false;
-
- #endregion Private Fields
-
- //------------------------------------------------------
- //
- // Private Structures / Classes
- //
- //------------------------------------------------------
-
- #region Private Structures Classes
[System.Flags]
private enum Flags : byte
@@ -653,8 +435,8 @@ namespace Avalonia.Controls
//
// bool flags
//
- UseSharedMinimum = 0x00000020, // when "1", definition will take into account shared state's minimum
- LayoutWasUpdated = 0x00000040, // set to "1" every time the parent grid is measured
+ UseSharedMinimum = 0x00000020, // when "1", definition will take into account shared state's minimum
+ LayoutWasUpdated = 0x00000040, // set to "1" every time the parent grid is measured
}
///
@@ -799,8 +581,8 @@ namespace Avalonia.Controls
for (int i = 0, count = _registry.Count; i < count; ++i)
{
- Debug.Assert( _userSize.GridUnitType == GridUnitType.Auto
- || _userSize.GridUnitType == GridUnitType.Pixel );
+ Debug.Assert(_userSize.GridUnitType == GridUnitType.Auto
+ || _userSize.GridUnitType == GridUnitType.Pixel);
GridLength currentGridLength = _registry[i].UserSizeValueCache;
if (currentGridLength.GridUnitType == GridUnitType.Pixel)
@@ -845,7 +627,7 @@ namespace Avalonia.Controls
{
DefinitionBase definitionBase = _registry[i];
- if (sharedMinSizeChanged || definitionBase.LayoutWasUpdated)
+ if (sharedMinSizeChanged || definitionBase.LayoutWasUpdated)
{
// if definition's min size is different, then need to re-measure
if (!MathUtilities.AreClose(sharedMinSize, definitionBase.MinSize))
@@ -857,7 +639,7 @@ namespace Avalonia.Controls
else
{
definitionBase.UseSharedMinimum = false;
-
+
// if measure is valid then also need to check arrange.
// Note: definitionBase.SizeCache is volatile but at this point
// it contains up-to-date final size
@@ -879,27 +661,34 @@ namespace Avalonia.Controls
_broadcastInvalidation = true;
}
-
- private readonly SharedSizeScope _sharedSizeScope; // the scope this state belongs to
- private readonly string _sharedSizeGroupId; // Id of the shared size group this object is servicing
- private readonly List _registry; // registry of participating definitions
- private readonly EventHandler _layoutUpdated; // instance event handler for layout updated event
- private Control _layoutUpdatedHost; // Control for which layout updated event handler is registered
- private bool _broadcastInvalidation; // "true" when broadcasting of invalidation is needed
- private bool _userSizeValid; // "true" when _userSize is up to date
- private GridLength _userSize; // shared state
- private double _minSize; // shared state
- }
- #endregion Private Structures Classes
+ // the scope this state belongs to
+ private readonly SharedSizeScope _sharedSizeScope;
+
+ // Id of the shared size group this object is servicing
+ private readonly string _sharedSizeGroupId;
+
+ // Registry of participating definitions
+ private readonly List _registry;
- //------------------------------------------------------
- //
- // Properties
- //
- //------------------------------------------------------
+ // Instance event handler for layout updated event
+ private readonly EventHandler _layoutUpdated;
- #region Properties
+ // Control for which layout updated event handler is registered
+ private Control _layoutUpdatedHost;
+
+ // "true" when broadcasting of invalidation is needed
+ private bool _broadcastInvalidation;
+
+ // "true" when _userSize is up to date
+ private bool _userSizeValid;
+
+ // shared state
+ private GridLength _userSize;
+
+ // shared state
+ private double _minSize;
+ }
///
/// Private shared size scope property holds a collection of shared state objects for the a given shared size scope.
@@ -931,7 +720,7 @@ namespace Avalonia.Controls
public static readonly AttachedProperty SharedSizeGroupProperty =
AvaloniaProperty.RegisterAttached(
"SharedSizeGroup",
- validate:SharedSizeGroupPropertyValueValid);
+ validate: SharedSizeGroupPropertyValueValid);
///
/// Static ctor. Used for static registration of properties.
@@ -941,7 +730,5 @@ namespace Avalonia.Controls
SharedSizeGroupProperty.Changed.AddClassHandler(OnSharedSizeGroupPropertyChanged);
PrivateSharedSizeScopeProperty.Changed.AddClassHandler(OnPrivateSharedSizeScopePropertyChanged);
}
-
- #endregion Properties
}
}
diff --git a/src/Avalonia.Controls/DefinitionList.cs b/src/Avalonia.Controls/DefinitionList.cs
index b36ca9ce8a..97d92bdcb7 100644
--- a/src/Avalonia.Controls/DefinitionList.cs
+++ b/src/Avalonia.Controls/DefinitionList.cs
@@ -10,6 +10,12 @@ namespace Avalonia.Controls
{
public abstract class DefinitionList : AvaloniaList where T : DefinitionBase
{
+ public DefinitionList()
+ {
+ ResetBehavior = ResetBehavior.Remove;
+ CollectionChanged += OnCollectionChanged;
+ }
+
internal bool IsDirty = true;
private Grid _parent;
@@ -19,7 +25,6 @@ namespace Avalonia.Controls
set => SetParent(value);
}
-
private void SetParent(Grid value)
{
_parent = value;
diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs
index 6d3b9f37cf..4f41b0bf1e 100644
--- a/src/Avalonia.Controls/Grid.cs
+++ b/src/Avalonia.Controls/Grid.cs
@@ -22,12 +22,6 @@ namespace Avalonia.Controls
///
public class Grid : Panel
{
- //------------------------------------------------------
- //
- // Constructors
- //
- //------------------------------------------------------
-
static Grid()
{
IsSharedSizeScopeProperty.Changed.AddClassHandler(DefinitionBase.OnIsSharedSizeScopePropertyChanged);
@@ -47,42 +41,6 @@ namespace Avalonia.Controls
{
}
- //------------------------------------------------------
- //
- // Public Methods
- //
- //------------------------------------------------------
-
-
- ///
- ///
- ///
- /* protected internal override IEnumerator LogicalChildren
- {
- get
- {
- // empty panel or a panel being used as the items
- // host has *no* logical children; give empty enumerator
- bool noChildren = (base.VisualChildrenCount == 0) || IsItemsHost;
-
- if (noChildren)
- {
- ExtendedData extData = ExtData;
-
- if ( extData == null
- || ( (extData.ColumnDefinitions == null || extData.ColumnDefinitions.Count == 0)
- && (extData.RowDefinitions == null || extData.RowDefinitions.Count == 0) )
- )
- {
- // grid is empty
- return EmptyEnumerator.Instance;
- }
- }
-
- return (new GridChildrenCollectionEnumeratorSimple(this, !noChildren));
- }
- } */
-
///
/// Helper for setting Column property on a Control.
///
@@ -193,12 +151,6 @@ namespace Avalonia.Controls
return element.GetValue(IsSharedSizeScopeProperty);
}
- //------------------------------------------------------
- //
- // Public Properties
- //
- //------------------------------------------------------
-
///
/// ShowGridLines property.
///
@@ -248,52 +200,6 @@ namespace Avalonia.Controls
}
}
- //------------------------------------------------------
- //
- // Protected Methods
- //
- //------------------------------------------------------
-
- /* ///
- /// Derived class must implement to support Visual children. The method must return
- /// the child at the specified index. Index must be between 0 and GetVisualChildrenCount-1.
- ///
- /// By default a Visual does not have any children.
- ///
- /// Remark:
- /// During this virtual call it is not valid to modify the Visual tree.
- ///
- protected override Visual GetVisualChild(int index)
- {
- // because "base.Count + 1" for GridLinesRenderer
- // argument checking done at the base class
- if(index == base.VisualChildrenCount)
- {
- if (_gridLinesRenderer == null)
- {
- throw new ArgumentOutOfRangeException("index", index, SR.Get(SRID.Visual_ArgumentOutOfRange));
- }
- return _gridLinesRenderer;
- }
- else return base.GetVisualChild(index);
- }
-
- ///
- /// Derived classes override this property to enable the Visual code to enumerate
- /// the Visual children. Derived classes need to return the number of children
- /// from this method.
- ///
- /// By default a Visual does not have any children.
- ///
- /// Remark: During this virtual method the Visual tree must not be modified.
- ///
- protected override int VisualChildrenCount
- {
- //since GridLinesRenderer has not been added as a child, so we do not subtract
- get { return base.VisualChildrenCount + (_gridLinesRenderer != null ? 1 : 0); }
- }*/
-
-
///
/// Content measurement.
///
@@ -306,8 +212,6 @@ namespace Avalonia.Controls
try
{
-
-
ListenToNotifications = true;
MeasureOverrideInProgress = true;
@@ -550,7 +454,7 @@ namespace Avalonia.Controls
// also use a count heuristic to break a loop in case of one.
bool hasDesiredSizeUChanged = false;
- int cnt=0;
+ int cnt = 0;
// Cache Group2MinWidths & Group3MinHeights
double[] group2MinSizes = CacheMinSizes(extData.CellGroup2, false);
@@ -582,17 +486,14 @@ namespace Avalonia.Controls
MeasureCellsGroup(extData.CellGroup4, constraint, false, false);
-
gridDesiredSize = new Size(
CalculateDesiredSize(DefinitionsU),
CalculateDesiredSize(DefinitionsV));
-
}
}
finally
{
MeasureOverrideInProgress = false;
-
}
return (gridDesiredSize);
@@ -606,8 +507,6 @@ namespace Avalonia.Controls
{
try
{
-
-
ArrangeOverrideInProgress = true;
if (_data == null)
@@ -627,13 +526,9 @@ namespace Avalonia.Controls
{
Debug.Assert(DefinitionsU.Count > 0 && DefinitionsV.Count > 0);
-
-
SetFinalSize(DefinitionsU, arrangeSize.Width, true);
SetFinalSize(DefinitionsV, arrangeSize.Height, false);
-
-
var children = this.Children;
for (int currentCell = 0; currentCell < PrivateCells.Length; ++currentCell)
@@ -653,11 +548,11 @@ namespace Avalonia.Controls
columnIndex == 0 ? 0.0 : DefinitionsU[columnIndex].FinalOffset,
rowIndex == 0 ? 0.0 : DefinitionsV[rowIndex].FinalOffset,
GetFinalSizeForRange(DefinitionsU, columnIndex, columnSpan),
- GetFinalSizeForRange(DefinitionsV, rowIndex, rowSpan) );
+ GetFinalSizeForRange(DefinitionsV, rowIndex, rowSpan));
+
-
cell.Arrange(cellRect);
-
+
}
// update render bound on grid lines renderer visual
@@ -669,31 +564,12 @@ namespace Avalonia.Controls
{
SetValid();
ArrangeOverrideInProgress = false;
-
}
return (arrangeSize);
}
///
- ///
- ///
- /*protected internal override void OnVisualChildrenChanged(
- AvaloniaObject visualAdded,
- AvaloniaObject visualRemoved)
- {
- CellsStructureDirty = true;
-
- base.OnVisualChildrenChanged(visualAdded, visualRemoved);
- }*/
-
- //------------------------------------------------------
- //
- // Internal Methods
- //
- //------------------------------------------------------
-
- ///
- /// Invalidates grid caches and makes the grid dirty for measure.
+ /// Invalidates grid caches and makes the grid dirty for measure.
///
internal void Invalidate()
{
@@ -702,10 +578,10 @@ namespace Avalonia.Controls
}
///
- /// Returns final width for a column.
+ /// Returns final width for a column.
///
///
- /// Used from public ColumnDefinition ActualWidth. Calculates final width using offset data.
+ /// Used from public ColumnDefinition ActualWidth. Calculates final width using offset data.
///
internal double GetFinalColumnDefinitionWidth(int columnIndex)
{
@@ -724,10 +600,10 @@ namespace Avalonia.Controls
}
///
- /// Returns final height for a row.
+ /// Returns final height for a row.
///
///
- /// Used from public RowDefinition ActualHeight. Calculates final height using offset data.
+ /// Used from public RowDefinition ActualHeight. Calculates final height using offset data.
///
internal double GetFinalRowDefinitionHeight(int rowIndex)
{
@@ -745,12 +621,6 @@ namespace Avalonia.Controls
return (value);
}
- //------------------------------------------------------
- //
- // Internal Properties
- //
- //------------------------------------------------------
-
///
/// Convenience accessor to MeasureOverrideInProgress bit flag.
///
@@ -781,32 +651,22 @@ namespace Avalonia.Controls
///
/// Convenience accessor to ValidDefinitionsVStructure bit flag.
///
- internal bool RowDefinitionsDirty
+ internal bool RowDefinitionsDirty
{
get => RowDefinitions?.IsDirty ?? false;
set => RowDefinitions.IsDirty = value;
}
- //------------------------------------------------------
- //
- // Private Methods
- //
- //------------------------------------------------------
-
///
/// Lays out cells according to rows and columns, and creates lookup grids.
///
private void ValidateCells()
{
-
-
if (CellsStructureDirty)
{
ValidateCellsCore();
CellsStructureDirty = false;
}
-
-
}
///
@@ -837,11 +697,8 @@ namespace Avalonia.Controls
CellCache cell = new CellCache();
- //
- // read and cache child positioning properties
- //
- // read indices from the corresponding properties
+ // Read indices from the corresponding properties:
// clamp to value < number_of_columns
// column >= 0 is guaranteed by property value validation callback
cell.ColumnIndex = Math.Min(GetColumn((Control)child), DefinitionsU.Count - 1);
@@ -849,7 +706,7 @@ namespace Avalonia.Controls
// row >= 0 is guaranteed by property value validation callback
cell.RowIndex = Math.Min(GetRow((Control)child), DefinitionsV.Count - 1);
- // read span properties
+ // Read span properties:
// clamp to not exceed beyond right side of the grid
// column_span > 0 is guaranteed by property value validation callback
cell.ColumnSpan = Math.Min(GetColumnSpan((Control)child), DefinitionsU.Count - cell.ColumnIndex);
@@ -861,9 +718,7 @@ namespace Avalonia.Controls
Debug.Assert(0 <= cell.ColumnIndex && cell.ColumnIndex < DefinitionsU.Count);
Debug.Assert(0 <= cell.RowIndex && cell.RowIndex < DefinitionsV.Count);
- //
- // calculate and cache length types for the child
- //
+ // Calculate and cache length types for the child.
cell.SizeTypeU = GetLengthTypeForRange(DefinitionsU, cell.ColumnIndex, cell.ColumnSpan);
cell.SizeTypeV = GetLengthTypeForRange(DefinitionsV, cell.RowIndex, cell.RowSpan);
@@ -871,9 +726,7 @@ namespace Avalonia.Controls
hasStarCellsU |= cell.IsStarU;
hasStarCellsV |= cell.IsStarV;
- //
- // distribute cells into four groups.
- //
+ // Distribute cells into four groups.
if (!cell.IsStarV)
{
@@ -887,15 +740,15 @@ namespace Avalonia.Controls
cell.Next = extData.CellGroup3;
extData.CellGroup3 = i;
- // remember if this cell belongs to auto row
+ // Remember if this cell belongs to auto row
hasGroup3CellsInAutoRows |= cell.IsAutoV;
}
}
else
{
- if ( cell.IsAutoU
- // note below: if spans through Star column it is NOT Auto
- && !cell.IsStarU )
+ if (cell.IsAutoU
+ // Note below: if spans through Star column it is NOT Auto
+ && !cell.IsStarU)
{
cell.Next = extData.CellGroup2;
extData.CellGroup2 = i;
@@ -986,7 +839,7 @@ namespace Avalonia.Controls
extData.DefinitionsV = new DefinitionBase[] { new RowDefinition() { Parent = this } };
}
else
- {
+ {
extData.DefinitionsV = extData.RowDefinitions;
}
}
@@ -1053,7 +906,7 @@ namespace Avalonia.Controls
{
double[] minSizes = isRows ? new double[DefinitionsV.Count] : new double[DefinitionsU.Count];
- for (int j=0; j (double)o )
+ if (o == null
+ || value > (double)o)
{
store[key] = value;
}
@@ -1235,13 +1088,13 @@ namespace Avalonia.Controls
int cell,
bool forceInfinityV)
{
-
+
double cellMeasureWidth;
double cellMeasureHeight;
- if ( PrivateCells[cell].IsAutoU
- && !PrivateCells[cell].IsStarU )
+ if (PrivateCells[cell].IsAutoU
+ && !PrivateCells[cell].IsStarU)
{
// if cell belongs to at least one Auto column and not a single Star column
// then it should be calculated "to content", thus it is possible to "shortcut"
@@ -1261,8 +1114,8 @@ namespace Avalonia.Controls
{
cellMeasureHeight = double.PositiveInfinity;
}
- else if ( PrivateCells[cell].IsAutoV
- && !PrivateCells[cell].IsStarV )
+ else if (PrivateCells[cell].IsAutoV
+ && !PrivateCells[cell].IsStarV)
{
// if cell belongs to at least one Auto row and not a single Star row
// then it should be calculated "to content", thus it is possible to "shortcut"
@@ -1277,19 +1130,18 @@ namespace Avalonia.Controls
PrivateCells[cell].RowSpan);
}
-
+
var child = this.Children[cell];
if (child != null)
{
Size childConstraint = new Size(cellMeasureWidth, cellMeasureHeight);
child.Measure(childConstraint);
}
-
-
- }
+ }
+
///
/// Calculates one dimensional measure size for given definitions' range.
///
@@ -1393,12 +1245,12 @@ namespace Avalonia.Controls
// sanity check: no matter what, but min size must always be the smaller;
// max size must be the biggest; and preferred should be in between
- Debug.Assert( minSize <= preferredSize
- && preferredSize <= maxSize
- && rangeMinSize <= rangePreferredSize
- && rangePreferredSize <= rangeMaxSize );
+ Debug.Assert(minSize <= preferredSize
+ && preferredSize <= maxSize
+ && rangeMinSize <= rangePreferredSize
+ && rangePreferredSize <= rangeMaxSize);
- if (maxMaxSize < maxSize) maxMaxSize = maxSize;
+ if (maxMaxSize < maxSize) maxMaxSize = maxSize;
if (definitions[i].UserSize.IsAuto) autoDefinitionsCount++;
tempDefinitions[i - start] = definitions[i];
}
@@ -1492,8 +1344,8 @@ namespace Avalonia.Controls
//
double equalSize = requestedSize / count;
- if ( equalSize < maxMaxSize
- && !_AreClose(equalSize, maxMaxSize) )
+ if (equalSize < maxMaxSize
+ && !_AreClose(equalSize, maxMaxSize))
{
// equi-size is less than maximum of maxSizes.
// in this case distribute so that smaller definitions grow faster than
@@ -1502,12 +1354,12 @@ namespace Avalonia.Controls
double sizeToDistribute = requestedSize - rangeMaxSize;
// sanity check: totalRemainingSize and sizeToDistribute must be real positive numbers
- Debug.Assert( !double.IsInfinity(totalRemainingSize)
- && !double.IsNaN(totalRemainingSize)
- && totalRemainingSize > 0
- && !double.IsInfinity(sizeToDistribute)
- && !double.IsNaN(sizeToDistribute)
- && sizeToDistribute > 0 );
+ Debug.Assert(!double.IsInfinity(totalRemainingSize)
+ && !double.IsNaN(totalRemainingSize)
+ && totalRemainingSize > 0
+ && !double.IsInfinity(sizeToDistribute)
+ && !double.IsNaN(sizeToDistribute)
+ && sizeToDistribute > 0);
for (int i = 0; i < count; ++i)
{
@@ -1543,105 +1395,10 @@ namespace Avalonia.Controls
IReadOnlyList definitions,
double availableSize)
{
- // if (FrameworkAppContextSwitches.GridStarDefinitionsCanExceedAvailableSpace)
- // {
- // ResolveStarLegacy(definitions, availableSize);
- // }
- // else
- // {
- ResolveStarMaxDiscrepancy(definitions, availableSize);
- // }
- }
-
- // original implementation, used from 3.0 through 4.6.2
- private void ResolveStarLegacy(
- IReadOnlyList definitions,
- double availableSize)
- {
- DefinitionBase[] tempDefinitions = TempDefinitions;
- int starDefinitionsCount = 0;
- double takenSize = 0;
-
- for (int i = 0; i < definitions.Count; ++i)
- {
- switch (definitions[i].SizeType)
- {
- case (LayoutTimeSizeType.Auto):
- takenSize += definitions[i].MinSize;
- break;
- case (LayoutTimeSizeType.Pixel):
- takenSize += definitions[i].MeasureSize;
- break;
- case (LayoutTimeSizeType.Star):
- {
- tempDefinitions[starDefinitionsCount++] = definitions[i];
-
- double starValue = definitions[i].UserSize.Value;
-
- if (_IsZero(starValue))
- {
- definitions[i].MeasureSize = 0;
- definitions[i].SizeCache = 0;
- }
- else
- {
- // clipping by c_starClip guarantees that sum of even a very big number of max'ed out star values
- // can be summed up without overflow
- starValue = Math.Min(starValue, c_starClip);
-
- // Note: normalized star value is temporary cached into MeasureSize
- definitions[i].MeasureSize = starValue;
- double maxSize = Math.Max(definitions[i].MinSize, definitions[i].UserMaxSize);
- maxSize = Math.Min(maxSize, c_starClip);
- definitions[i].SizeCache = maxSize / starValue;
- }
- }
- break;
- }
- }
-
- if (starDefinitionsCount > 0)
- {
- Array.Sort(tempDefinitions, 0, starDefinitionsCount, s_starDistributionOrderComparer);
-
- // the 'do {} while' loop below calculates sum of star weights in order to avoid fp overflow...
- // partial sum value is stored in each definition's SizeCache member.
- // this way the algorithm guarantees (starValue <= definition.SizeCache) and thus
- // (starValue / definition.SizeCache) will never overflow due to sum of star weights becoming zero.
- // this is an important change from previous implementation where the following was possible:
- // ((BigValueStar + SmallValueStar) - BigValueStar) resulting in 0...
- double allStarWeights = 0;
- int i = starDefinitionsCount - 1;
- do
- {
- allStarWeights += tempDefinitions[i].MeasureSize;
- tempDefinitions[i].SizeCache = allStarWeights;
- } while (--i >= 0);
-
- i = 0;
- do
- {
- double resolvedSize;
- double starValue = tempDefinitions[i].MeasureSize;
-
- if (_IsZero(starValue))
- {
- resolvedSize = tempDefinitions[i].MinSize;
- }
- else
- {
- double userSize = Math.Max(availableSize - takenSize, 0.0) * (starValue / tempDefinitions[i].SizeCache);
- resolvedSize = Math.Min(userSize, tempDefinitions[i].UserMaxSize);
- resolvedSize = Math.Max(tempDefinitions[i].MinSize, resolvedSize);
- }
-
- tempDefinitions[i].MeasureSize = resolvedSize;
- takenSize += resolvedSize;
- } while (++i < starDefinitionsCount);
- }
+ ResolveStarMaxDiscrepancy(definitions, availableSize);
}
- // new implementation as of 4.7. Several improvements:
+ // New implementation as of 4.7. Several improvements:
// 1. Allocate to *-defs hitting their min or max constraints, before allocating
// to other *-defs. A def that hits its min uses more space than its
// proportional share, reducing the space available to everyone else.
@@ -1668,7 +1425,7 @@ namespace Avalonia.Controls
// Phase 1. Determine the maximum *-weight and prepare to adjust *-weights
double maxStar = 0.0;
- for (int i=0; i definitions,
- double finalSize,
- bool columns)
- {
- int starDefinitionsCount = 0; // traverses form the first entry up
- int nonStarIndex = definitions.Count; // traverses from the last entry down
- double allPreferredArrangeSize = 0;
- bool useLayoutRounding = this.UseLayoutRounding;
- int[] definitionIndices = DefinitionIndices;
- double[] roundingErrors = null;
-
- // If using layout rounding, check whether rounding needs to compensate for high DPI
- double dpi = 1.0;
-
- if (useLayoutRounding)
- {
- // DpiScale dpiScale = GetDpi();
- // dpi = columns ? dpiScale.DpiScaleX : dpiScale.DpiScaleY;
- dpi = (VisualRoot as Layout.ILayoutRoot)?.LayoutScaling ?? 1.0;
- roundingErrors = RoundingErrors;
- }
-
- for (int i = 0; i < definitions.Count; ++i)
- {
- // if definition is shared then is cannot be star
- Debug.Assert(!definitions[i].IsShared || !definitions[i].UserSize.IsStar);
-
- if (definitions[i].UserSize.IsStar)
- {
- double starValue = definitions[i].UserSize.Value;
-
- if (_IsZero(starValue))
- {
- // cach normilized star value temporary into MeasureSize
- definitions[i].MeasureSize = 0;
- definitions[i].SizeCache = 0;
- }
- else
- {
- // clipping by c_starClip guarantees that sum of even a very big number of max'ed out star values
- // can be summed up without overflow
- starValue = Math.Min(starValue, c_starClip);
-
- // Note: normalized star value is temporary cached into MeasureSize
- definitions[i].MeasureSize = starValue;
- double maxSize = Math.Max(definitions[i].MinSizeForArrange, definitions[i].UserMaxSize);
- maxSize = Math.Min(maxSize, c_starClip);
- definitions[i].SizeCache = maxSize / starValue;
- if (useLayoutRounding)
- {
- roundingErrors[i] = definitions[i].SizeCache;
- definitions[i].SizeCache = MathUtilities.RoundLayoutValue(definitions[i].SizeCache, dpi);
- }
- }
- definitionIndices[starDefinitionsCount++] = i;
- }
- else
- {
- double userSize = 0;
-
- switch (definitions[i].UserSize.GridUnitType)
- {
- case (GridUnitType.Pixel):
- userSize = definitions[i].UserSize.Value;
- break;
-
- case (GridUnitType.Auto):
- userSize = definitions[i].MinSizeForArrange;
- break;
- }
-
- double userMaxSize;
-
- if (definitions[i].IsShared)
- {
- // overriding userMaxSize effectively prevents squishy-ness.
- // this is a "solution" to avoid shared definitions from been sized to
- // different final size at arrange time, if / when different grids receive
- // different final sizes.
- userMaxSize = userSize;
- }
- else
- {
- userMaxSize = definitions[i].UserMaxSize;
- }
-
- definitions[i].SizeCache = Math.Max(definitions[i].MinSizeForArrange, Math.Min(userSize, userMaxSize));
- if (useLayoutRounding)
- {
- roundingErrors[i] = definitions[i].SizeCache;
- definitions[i].SizeCache = MathUtilities.RoundLayoutValue(definitions[i].SizeCache, dpi);
- }
-
- allPreferredArrangeSize += definitions[i].SizeCache;
- definitionIndices[--nonStarIndex] = i;
- }
- }
-
- // indices should meet
- Debug.Assert(nonStarIndex == starDefinitionsCount);
-
- if (starDefinitionsCount > 0)
- {
- StarDistributionOrderIndexComparer starDistributionOrderIndexComparer = new StarDistributionOrderIndexComparer(definitions);
- Array.Sort(definitionIndices, 0, starDefinitionsCount, starDistributionOrderIndexComparer);
-
- // the 'do {} while' loop below calculates sum of star weights in order to avoid fp overflow...
- // partial sum value is stored in each definition's SizeCache member.
- // this way the algorithm guarantees (starValue <= definition.SizeCache) and thus
- // (starValue / definition.SizeCache) will never overflow due to sum of star weights becoming zero.
- // this is an important change from previous implementation where the following was possible:
- // ((BigValueStar + SmallValueStar) - BigValueStar) resulting in 0...
- double allStarWeights = 0;
- int i = starDefinitionsCount - 1;
- do
- {
- allStarWeights += definitions[definitionIndices[i]].MeasureSize;
- definitions[definitionIndices[i]].SizeCache = allStarWeights;
- } while (--i >= 0);
-
- i = 0;
- do
- {
- double resolvedSize;
- double starValue = definitions[definitionIndices[i]].MeasureSize;
-
- if (_IsZero(starValue))
- {
- resolvedSize = definitions[definitionIndices[i]].MinSizeForArrange;
- }
- else
- {
- double userSize = Math.Max(finalSize - allPreferredArrangeSize, 0.0) * (starValue / definitions[definitionIndices[i]].SizeCache);
- resolvedSize = Math.Min(userSize, definitions[definitionIndices[i]].UserMaxSize);
- resolvedSize = Math.Max(definitions[definitionIndices[i]].MinSizeForArrange, resolvedSize);
- }
-
- definitions[definitionIndices[i]].SizeCache = resolvedSize;
- if (useLayoutRounding)
- {
- roundingErrors[definitionIndices[i]] = definitions[definitionIndices[i]].SizeCache;
- definitions[definitionIndices[i]].SizeCache = MathUtilities.RoundLayoutValue(definitions[definitionIndices[i]].SizeCache, dpi);
- }
-
- allPreferredArrangeSize += definitions[definitionIndices[i]].SizeCache;
- } while (++i < starDefinitionsCount);
- }
-
- if ( allPreferredArrangeSize > finalSize
- && !_AreClose(allPreferredArrangeSize, finalSize) )
- {
- DistributionOrderIndexComparer distributionOrderIndexComparer = new DistributionOrderIndexComparer(definitions);
- Array.Sort(definitionIndices, 0, definitions.Count, distributionOrderIndexComparer);
- double sizeToDistribute = finalSize - allPreferredArrangeSize;
-
- for (int i = 0; i < definitions.Count; ++i)
- {
- int definitionIndex = definitionIndices[i];
- double final = definitions[definitionIndex].SizeCache + (sizeToDistribute / (definitions.Count - i));
- double finalOld = final;
- final = Math.Max(final, definitions[definitionIndex].MinSizeForArrange);
- final = Math.Min(final, definitions[definitionIndex].SizeCache);
-
- if (useLayoutRounding)
- {
- roundingErrors[definitionIndex] = final;
- final = MathUtilities.RoundLayoutValue(finalOld, dpi);
- final = Math.Max(final, definitions[definitionIndex].MinSizeForArrange);
- final = Math.Min(final, definitions[definitionIndex].SizeCache);
- }
-
- sizeToDistribute -= (final - definitions[definitionIndex].SizeCache);
- definitions[definitionIndex].SizeCache = final;
- }
-
- allPreferredArrangeSize = finalSize - sizeToDistribute;
- }
-
- if (useLayoutRounding)
- {
- if (!_AreClose(allPreferredArrangeSize, finalSize))
- {
- // Compute deltas
- for (int i = 0; i < definitions.Count; ++i)
- {
- roundingErrors[i] = roundingErrors[i] - definitions[i].SizeCache;
- definitionIndices[i] = i;
- }
-
- // Sort rounding errors
- RoundingErrorIndexComparer roundingErrorIndexComparer = new RoundingErrorIndexComparer(roundingErrors);
- Array.Sort(definitionIndices, 0, definitions.Count, roundingErrorIndexComparer);
- double adjustedSize = allPreferredArrangeSize;
- double dpiIncrement = MathUtilities.RoundLayoutValue(1.0, dpi);
-
- if (allPreferredArrangeSize > finalSize)
- {
- int i = definitions.Count - 1;
- while ((adjustedSize > finalSize && !_AreClose(adjustedSize, finalSize)) && i >= 0)
- {
- DefinitionBase definition = definitions[definitionIndices[i]];
- double final = definition.SizeCache - dpiIncrement;
- final = Math.Max(final, definition.MinSizeForArrange);
- if (final < definition.SizeCache)
- {
- adjustedSize -= dpiIncrement;
- }
- definition.SizeCache = final;
- i--;
- }
- }
- else if (allPreferredArrangeSize < finalSize)
- {
- int i = 0;
- while ((adjustedSize < finalSize && !_AreClose(adjustedSize, finalSize)) && i < definitions.Count)
- {
- DefinitionBase definition = definitions[definitionIndices[i]];
- double final = definition.SizeCache + dpiIncrement;
- final = Math.Max(final, definition.MinSizeForArrange);
- if (final > definition.SizeCache)
- {
- adjustedSize += dpiIncrement;
- }
- definition.SizeCache = final;
- i++;
- }
- }
- }
- }
-
- definitions[0].FinalOffset = 0.0;
- for (int i = 0; i < definitions.Count; ++i)
- {
- definitions[(i + 1) % definitions.Count].FinalOffset = definitions[i].FinalOffset + definitions[i].SizeCache;
- }
+ SetFinalSizeMaxDiscrepancy(definitions, finalSize, columns);
}
// new implementation, as of 4.7. This incorporates the same algorithm
@@ -2251,7 +1762,7 @@ namespace Avalonia.Controls
// Phase 1. Determine the maximum *-weight and prepare to adjust *-weights
double maxStar = 0.0;
- for (int i=0; i finalSize)
{
@@ -2694,7 +2204,7 @@ namespace Avalonia.Controls
/// if the max constraint has higher discrepancy
/// null if proportion doesn't fail a min or max constraint
/// The discrepancy is the ratio of the proportion to the max- or min-ratio.
- /// When both ratios hit the constraint, minRatio < proportion > maxRatio,
+ /// When both ratios hit the constraint, minRatio < proportion < maxRatio,
/// and the minRatio has higher discrepancy if
/// (proportion / minRatio) > (maxRatio / proportion)
///
@@ -2782,8 +2292,8 @@ namespace Avalonia.Controls
ExtendedData extData = ExtData;
if (extData != null)
{
-// for (int i = 0; i < PrivateColumnCount; ++i) DefinitionsU[i].SetValid ();
-// for (int i = 0; i < PrivateRowCount; ++i) DefinitionsV[i].SetValid ();
+ // for (int i = 0; i < PrivateColumnCount; ++i) DefinitionsU[i].SetValid ();
+ // for (int i = 0; i < PrivateRowCount; ++i) DefinitionsV[i].SetValid ();
if (extData.TempDefinitions != null)
{
@@ -2793,29 +2303,7 @@ namespace Avalonia.Controls
}
}
}
-
- ///
- /// Returns true if ColumnDefinitions collection is not empty
- ///
- public bool ShouldSerializeColumnDefinitions()
- {
- ExtendedData extData = ExtData;
- return ( extData != null
- && extData.ColumnDefinitions != null
- && extData.ColumnDefinitions.Count > 0 );
- }
-
- ///
- /// Returns true if RowDefinitions collection is not empty
- ///
- public bool ShouldSerializeRowDefinitions()
- {
- ExtendedData extData = ExtData;
- return ( extData != null
- && extData.RowDefinitions != null
- && extData.RowDefinitions.Count > 0 );
- }
-
+
///
/// Synchronized ShowGridLines property with the state of the grid's visual collection
/// by adding / removing GridLinesRenderer visual.
@@ -2872,25 +2360,19 @@ namespace Avalonia.Controls
return (flags == 0 || (_flags & flags) != 0);
}
- ///
- ///
- ///
private static void OnShowGridLinesPropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
{
Grid grid = (Grid)d;
- if ( grid.ExtData != null // trivial grid is 1 by 1. there is no grid lines anyway
- && grid.ListenToNotifications)
+ if (grid.ExtData != null // trivial grid is 1 by 1. there is no grid lines anyway
+ && grid.ListenToNotifications)
{
grid.InvalidateVisual();
}
- grid.SetFlags((bool) e.NewValue, Flags.ShowGridLinesPropertyValue);
+ grid.SetFlags((bool)e.NewValue, Flags.ShowGridLinesPropertyValue);
}
- ///
- ///
- ///
private static void OnCellAttachedPropertyChanged(AvaloniaObject d, AvaloniaPropertyChangedEventArgs e)
{
Visual child = d as Visual;
@@ -2898,36 +2380,20 @@ namespace Avalonia.Controls
if (child != null)
{
Grid grid = child.GetVisualParent();
- if ( grid != null
- && grid.ExtData != null
- && grid.ListenToNotifications )
+ if (grid != null
+ && grid.ExtData != null
+ && grid.ListenToNotifications)
{
grid.CellsStructureDirty = true;
}
}
}
- /* ///
- ///
- ///
- private static bool IsIntValueNotNegative(object value)
- {
- return ((int)value >= 0);
- }
-
- ///
- ///
- ///
- private static bool IsIntValueGreaterThanZero(object value)
- {
- return ((int)value > 0);
- }*/
-
///
/// Helper for Comparer methods.
///
///
- /// true iff one or both of x and y are null, in which case result holds
+ /// true if one or both of x and y are null, in which case result holds
/// the relative sort order.
///
private static bool CompareNullRefs(object x, object y, out int result)
@@ -2956,12 +2422,6 @@ namespace Avalonia.Controls
return (result != 2);
}
- //------------------------------------------------------
- //
- // Private Properties
- //
- //------------------------------------------------------
-
///
/// Private version returning array of column definitions.
///
@@ -2988,8 +2448,8 @@ namespace Avalonia.Controls
ExtendedData extData = ExtData;
int requiredLength = Math.Max(DefinitionsU.Count, DefinitionsV.Count) * 2;
- if ( extData.TempDefinitions == null
- || extData.TempDefinitions.Length < requiredLength )
+ if (extData.TempDefinitions == null
+ || extData.TempDefinitions.Length < requiredLength)
{
WeakReference tempDefinitionsWeakRef = (WeakReference)Thread.GetData(s_tempDefinitionsDataSlot);
if (tempDefinitionsWeakRef == null)
@@ -3000,8 +2460,8 @@ namespace Avalonia.Controls
else
{
extData.TempDefinitions = (DefinitionBase[])tempDefinitionsWeakRef.Target;
- if ( extData.TempDefinitions == null
- || extData.TempDefinitions.Length < requiredLength )
+ if (extData.TempDefinitions == null
+ || extData.TempDefinitions.Length < requiredLength)
{
extData.TempDefinitions = new DefinitionBase[requiredLength];
tempDefinitionsWeakRef.Target = extData.TempDefinitions;
@@ -3129,7 +2589,7 @@ namespace Avalonia.Controls
/// true if d == 0.
private static bool _IsZero(double d)
{
- return (Math.Abs(d) < c_epsilon);
+ return (Math.Abs(d) < double.Epsilon);
}
///
@@ -3140,7 +2600,7 @@ namespace Avalonia.Controls
/// true if d1 == d2
private static bool _AreClose(double d1, double d2)
{
- return (Math.Abs(d1 - d2) < c_epsilon);
+ return (Math.Abs(d1 - d2) < double.Epsilon);
}
///
@@ -3169,13 +2629,11 @@ namespace Avalonia.Controls
}
}
- //------------------------------------------------------
- //
- // Private Fields
- //
- //------------------------------------------------------
- private ExtendedData _data; // extended data instantiated on demand, for non-trivial case handling only
- private Flags _flags; // grid validity / property caches dirtiness flags
+ // Extended data instantiated on demand, for non-trivial case handling only
+ private ExtendedData _data;
+
+ // Grid validity / property caches dirtiness flags
+ private Flags _flags;
private GridLinesRenderer _gridLinesRenderer;
// Keeps track of definition indices.
@@ -3184,29 +2642,16 @@ namespace Avalonia.Controls
// Stores unrounded values and rounding errors during layout rounding.
double[] _roundingErrors;
- //------------------------------------------------------
- //
- // Static Fields
- //
- //------------------------------------------------------
- private const double c_epsilon = 1e-5; // used in fp calculations
- private const double c_starClip = 1e298; // used as maximum for clipping star values during normalization
- private const int c_layoutLoopMaxCount = 5; // 5 is an arbitrary constant chosen to end the measure loop
+ // 5 is an arbitrary constant chosen to end the measure loop
+ private const int c_layoutLoopMaxCount = 5;
+
private static readonly LocalDataStoreSlot s_tempDefinitionsDataSlot = Thread.AllocateDataSlot();
private static readonly IComparer s_spanPreferredDistributionOrderComparer = new SpanPreferredDistributionOrderComparer();
private static readonly IComparer s_spanMaxDistributionOrderComparer = new SpanMaxDistributionOrderComparer();
- private static readonly IComparer s_starDistributionOrderComparer = new StarDistributionOrderComparer();
- private static readonly IComparer s_distributionOrderComparer = new DistributionOrderComparer();
private static readonly IComparer s_minRatioComparer = new MinRatioComparer();
private static readonly IComparer s_maxRatioComparer = new MaxRatioComparer();
private static readonly IComparer s_starWeightComparer = new StarWeightComparer();
- //------------------------------------------------------
- //
- // Private Structures / Classes
- //
- //------------------------------------------------------
-
///
/// Extended data instantiated on demand, when grid handles non-trivial case.
///
@@ -3237,34 +2682,28 @@ namespace Avalonia.Controls
// * Valid???Layout flags indicate that layout time portion of the information
// stored on the objects should be updated.
//
- ValidDefinitionsUStructure = 0x00000001,
- ValidDefinitionsVStructure = 0x00000002,
- ValidCellsStructure = 0x00000004,
+ ValidDefinitionsUStructure = 0x00000001,
+ ValidDefinitionsVStructure = 0x00000002,
+ ValidCellsStructure = 0x00000004,
//
// boolean properties state
//
- ShowGridLinesPropertyValue = 0x00000100, // show grid lines ?
+ ShowGridLinesPropertyValue = 0x00000100, // show grid lines ?
//
// boolean flags
//
- ListenToNotifications = 0x00001000, // "0" when all notifications are ignored
- SizeToContentU = 0x00002000, // "1" if calculating to content in U direction
- SizeToContentV = 0x00004000, // "1" if calculating to content in V direction
- HasStarCellsU = 0x00008000, // "1" if at least one cell belongs to a Star column
- HasStarCellsV = 0x00010000, // "1" if at least one cell belongs to a Star row
- HasGroup3CellsInAutoRows = 0x00020000, // "1" if at least one cell of group 3 belongs to an Auto row
- MeasureOverrideInProgress = 0x00040000, // "1" while in the context of Grid.MeasureOverride
- ArrangeOverrideInProgress = 0x00080000, // "1" while in the context of Grid.ArrangeOverride
+ ListenToNotifications = 0x00001000, // "0" when all notifications are ignored
+ SizeToContentU = 0x00002000, // "1" if calculating to content in U direction
+ SizeToContentV = 0x00004000, // "1" if calculating to content in V direction
+ HasStarCellsU = 0x00008000, // "1" if at least one cell belongs to a Star column
+ HasStarCellsV = 0x00010000, // "1" if at least one cell belongs to a Star row
+ HasGroup3CellsInAutoRows = 0x00020000, // "1" if at least one cell of group 3 belongs to an Auto row
+ MeasureOverrideInProgress = 0x00040000, // "1" while in the context of Grid.MeasureOverride
+ ArrangeOverrideInProgress = 0x00080000, // "1" while in the context of Grid.ArrangeOverride
}
- //------------------------------------------------------
- //
- // Properties
- //
- //------------------------------------------------------
-
///
/// ShowGridLines property. This property is used mostly
/// for simplification of visual debuggig. When it is set
@@ -3289,8 +2728,11 @@ namespace Avalonia.Controls
AvaloniaProperty.RegisterAttached(
"Column",
defaultValue: 0,
- validate: (_, v) => { if (v >= 0) return v;
- else throw new ArgumentException("Invalid Grid.Column value."); });
+ validate: (_, v) =>
+ {
+ if (v >= 0) return v;
+ else throw new ArgumentException("Invalid Grid.Column value.");
+ });
///
/// Row property. This is an attached property.
@@ -3307,8 +2749,11 @@ namespace Avalonia.Controls
AvaloniaProperty.RegisterAttached(
"Row",
defaultValue: 0,
- validate: (_, v) => { if (v >= 0) return v;
- else throw new ArgumentException("Invalid Grid.Row value."); });
+ validate: (_, v) =>
+ {
+ if (v >= 0) return v;
+ else throw new ArgumentException("Invalid Grid.Row value.");
+ });
///
/// ColumnSpan property. This is an attached property.
@@ -3324,8 +2769,11 @@ namespace Avalonia.Controls
AvaloniaProperty.RegisterAttached(
"ColumnSpan",
defaultValue: 1,
- validate: (_, v) => { if (v >= 1) return v;
- else throw new ArgumentException("Invalid Grid.ColumnSpan value."); });
+ validate: (_, v) =>
+ {
+ if (v >= 1) return v;
+ else throw new ArgumentException("Invalid Grid.ColumnSpan value.");
+ });
///
/// RowSpan property. This is an attached property.
@@ -3341,8 +2789,11 @@ namespace Avalonia.Controls
AvaloniaProperty.RegisterAttached(
"RowSpan",
defaultValue: 1,
- validate: (_, v) => { if (v >= 1) return v;
- else throw new ArgumentException("Invalid Grid.RowSpan value."); });
+ validate: (_, v) =>
+ {
+ if (v >= 1) return v;
+ else throw new ArgumentException("Invalid Grid.RowSpan value.");
+ });
///
/// IsSharedSizeScope property marks scoping element for shared size.
@@ -3351,30 +2802,18 @@ namespace Avalonia.Controls
AvaloniaProperty.RegisterAttached(
"IsSharedSizeScope");
- //------------------------------------------------------
- //
- // Internal Structures / Classes
- //
- //------------------------------------------------------
-
///
/// LayoutTimeSizeType is used internally and reflects layout-time size type.
///
[System.Flags]
internal enum LayoutTimeSizeType : byte
{
- None = 0x00,
- Pixel = 0x01,
- Auto = 0x02,
- Star = 0x04,
+ None = 0x00,
+ Pixel = 0x01,
+ Auto = 0x02,
+ Star = 0x04,
}
- //------------------------------------------------------
- //
- // Private Structures / Classes
- //
- //------------------------------------------------------
-
///
/// CellCache stored calculated values of
/// 1. attached cell positioning properties;
@@ -3422,7 +2861,7 @@ namespace Avalonia.Controls
int hash = (_start ^ (_count << 2));
if (_u) hash &= 0x7ffffff;
- else hash |= 0x8000000;
+ else hash |= 0x8000000;
return (hash);
}
@@ -3433,10 +2872,10 @@ namespace Avalonia.Controls
public override bool Equals(object obj)
{
SpanKey sk = obj as SpanKey;
- return ( sk != null
- && sk._start == _start
- && sk._count == _count
- && sk._u == _u );
+ return (sk != null
+ && sk._start == _start
+ && sk._count == _count
+ && sk._u == _u);
}
///
@@ -3544,51 +2983,6 @@ namespace Avalonia.Controls
}
}
- ///
- /// StarDistributionOrderComparer.
- ///
- private class StarDistributionOrderComparer : IComparer
- {
- public int Compare(object x, object y)
- {
- DefinitionBase definitionX = x as DefinitionBase;
- DefinitionBase definitionY = y as DefinitionBase;
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- result = definitionX.SizeCache.CompareTo(definitionY.SizeCache);
- }
-
- return result;
- }
- }
-
- ///
- /// DistributionOrderComparer.
- ///
- private class DistributionOrderComparer: IComparer
- {
- public int Compare(object x, object y)
- {
- DefinitionBase definitionX = x as DefinitionBase;
- DefinitionBase definitionY = y as DefinitionBase;
-
- int result;
-
- if (!CompareNullRefs(definitionX, definitionY, out result))
- {
- double xprime = definitionX.SizeCache - definitionX.MinSizeForArrange;
- double yprime = definitionY.SizeCache - definitionY.MinSizeForArrange;
- result = xprime.CompareTo(yprime);
- }
-
- return result;
- }
- }
-
-
///
/// StarDistributionOrderIndexComparer.
///
@@ -3895,94 +3289,8 @@ namespace Avalonia.Controls
}
}
- /* ///
- /// Implementation of a simple enumerator of grid's logical children
- ///
- private class GridChildrenCollectionEnumeratorSimple : IEnumerator
- {
- internal GridChildrenCollectionEnumeratorSimple(Grid grid, bool includeChildren)
- {
- Debug.Assert(grid != null);
- _currentEnumerator = -1;
- _enumerator0 = new ColumnDefinitions.Enumerator(grid.ExtData != null ? grid.ExtData.ColumnDefinitions : null);
- _enumerator1 = new RowDefinitions.Enumerator(grid.ExtData != null ? grid.ExtData.RowDefinitions : null);
- // GridLineRenderer is NOT included into this enumerator.
- _enumerator2Index = 0;
- if (includeChildren)
- {
- _enumerator2Collection = grid.Children;
- _enumerator2Count = _enumerator2Collection.Count;
- }
- else
- {
- _enumerator2Collection = null;
- _enumerator2Count = 0;
- }
- }
-
- public bool MoveNext()
- {
- while (_currentEnumerator < 3)
- {
- if (_currentEnumerator >= 0)
- {
- switch (_currentEnumerator)
- {
- case (0): if (_enumerator0.MoveNext()) { _currentChild = _enumerator0.Current; return (true); } break;
- case (1): if (_enumerator1.MoveNext()) { _currentChild = _enumerator1.Current; return (true); } break;
- case (2): if (_enumerator2Index < _enumerator2Count)
- {
- _currentChild = _enumerator2Collection[_enumerator2Index];
- _enumerator2Index++;
- return (true);
- }
- break;
- }
- }
- _currentEnumerator++;
- }
- return (false);
- }
-
- public Object Current
- {
- get
- {
- if (_currentEnumerator == -1)
- {
- throw new InvalidOperationException(SR.Get(SRID.EnumeratorNotStarted));
- }
- if (_currentEnumerator >= 3)
- {
- throw new InvalidOperationException(SR.Get(SRID.EnumeratorReachedEnd));
- }
-
- // assert below is not true anymore since Controls allowes for null children
- //Debug.Assert(_currentChild != null);
- return (_currentChild);
- }
- }
-
- public void Reset()
- {
- _currentEnumerator = -1;
- _currentChild = null;
- _enumerator0.Reset();
- _enumerator1.Reset();
- _enumerator2Index = 0;
- }
-
- private int _currentEnumerator;
- private Object _currentChild;
- private ColumnDefinitions.Enumerator _enumerator0;
- private RowDefinitions.Enumerator _enumerator1;
- private Controls _enumerator2Collection;
- private int _enumerator2Index;
- private int _enumerator2Count;
- }*/
-
///
- /// Helper to render grid lines.
+ /// Helper for rendering grid lines.
///
internal class GridLinesRenderer : Control
{
@@ -3995,15 +3303,15 @@ namespace Avalonia.Controls
var ds1 = new DashStyle(dashArray, 0);
_oddDashPen = new Pen(Brushes.Blue,
- _penWidth,
- lineCap: PenLineCap.Flat,
- dashStyle: ds1);
+ _penWidth,
+ lineCap: PenLineCap.Flat,
+ dashStyle: ds1);
var ds2 = new DashStyle(dashArray, _dashLength);
_evenDashPen = new Pen(Brushes.Yellow,
- _penWidth,
- lineCap: PenLineCap.Flat,
- dashStyle: ds2);
+ _penWidth,
+ lineCap: PenLineCap.Flat,
+ dashStyle: ds2);
}
///
@@ -4052,7 +3360,6 @@ namespace Avalonia.Controls
internal void UpdateRenderBounds(Size arrangeSize)
{
_lastArrangeSize = arrangeSize;
- this.InvalidateMeasure();
this.InvalidateVisual();
}
@@ -4061,6 +3368,6 @@ namespace Avalonia.Controls
private const double _penWidth = 1.0; //
private static readonly Pen _oddDashPen; // first pen to draw dash
private static readonly Pen _evenDashPen; // second pen to draw dash
- }
+ }
}
}
diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs
index 2c8da58b44..6b5391454f 100644
--- a/src/Avalonia.Controls/Presenters/TextPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs
@@ -25,6 +25,9 @@ namespace Avalonia.Controls.Presenters
public static readonly StyledProperty SelectionForegroundBrushProperty =
AvaloniaProperty.Register(nameof(SelectionForegroundBrushProperty));
+ public static readonly StyledProperty CaretBrushProperty =
+ AvaloniaProperty.Register(nameof(CaretBrushProperty));
+
public static readonly DirectProperty SelectionStartProperty =
TextBox.SelectionStartProperty.AddOwner(
o => o.SelectionStart,
@@ -40,7 +43,7 @@ namespace Avalonia.Controls.Presenters
private int _selectionStart;
private int _selectionEnd;
private bool _caretBlink;
-
+
static TextPresenter()
{
AffectsRender(PasswordCharProperty);
@@ -95,6 +98,12 @@ namespace Avalonia.Controls.Presenters
get => GetValue(SelectionForegroundBrushProperty);
set => SetValue(SelectionForegroundBrushProperty, value);
}
+
+ public IBrush CaretBrush
+ {
+ get => GetValue(CaretBrushProperty);
+ set => SetValue(CaretBrushProperty, value);
+ }
public int SelectionStart
{
@@ -156,16 +165,21 @@ namespace Avalonia.Controls.Presenters
if (selectionStart == selectionEnd)
{
- var backgroundColor = (((Control)TemplatedParent).GetValue(BackgroundProperty) as SolidColorBrush)?.Color;
- var caretBrush = Brushes.Black;
+ var caretBrush = CaretBrush;
- if (backgroundColor.HasValue)
+ if (caretBrush is null)
{
- byte red = (byte)~(backgroundColor.Value.R);
- byte green = (byte)~(backgroundColor.Value.G);
- byte blue = (byte)~(backgroundColor.Value.B);
-
- caretBrush = new SolidColorBrush(Color.FromRgb(red, green, blue));
+ var backgroundColor = (((Control)TemplatedParent).GetValue(BackgroundProperty) as SolidColorBrush)?.Color;
+ if (backgroundColor.HasValue)
+ {
+ byte red = (byte)~(backgroundColor.Value.R);
+ byte green = (byte)~(backgroundColor.Value.G);
+ byte blue = (byte)~(backgroundColor.Value.B);
+
+ caretBrush = new SolidColorBrush(Color.FromRgb(red, green, blue));
+ }
+ else
+ caretBrush = Brushes.Black;
}
if (_caretBlink)
diff --git a/src/Avalonia.Controls/RowDefinitions.cs b/src/Avalonia.Controls/RowDefinitions.cs
index 3090844251..cf72cc8ba3 100644
--- a/src/Avalonia.Controls/RowDefinitions.cs
+++ b/src/Avalonia.Controls/RowDefinitions.cs
@@ -14,10 +14,8 @@ namespace Avalonia.Controls
///
/// Initializes a new instance of the class.
///
- public RowDefinitions()
+ public RowDefinitions() : base()
{
- ResetBehavior = ResetBehavior.Remove;
- CollectionChanged += OnCollectionChanged;
}
///
diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index 0a64c99a66..876e6a66a7 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -44,6 +44,9 @@ namespace Avalonia.Controls
public static readonly StyledProperty SelectionForegroundBrushProperty =
AvaloniaProperty.Register(nameof(SelectionForegroundBrushProperty));
+ public static readonly StyledProperty CaretBrushProperty =
+ AvaloniaProperty.Register(nameof(CaretBrushProperty));
+
public static readonly DirectProperty SelectionStartProperty =
AvaloniaProperty.RegisterDirect(
nameof(SelectionStart),
@@ -187,6 +190,12 @@ namespace Avalonia.Controls
set => SetValue(SelectionForegroundBrushProperty, value);
}
+ public IBrush CaretBrush
+ {
+ get => GetValue(CaretBrushProperty);
+ set => SetValue(CaretBrushProperty, value);
+ }
+
public int SelectionStart
{
get
diff --git a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
index 801ed74ca0..a0e86a53b0 100644
--- a/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
+++ b/src/Avalonia.DesignerSupport/Remote/RemoteDesignerEntryPoint.cs
@@ -9,7 +9,6 @@ using Avalonia.Remote.Protocol;
using Avalonia.Remote.Protocol.Designer;
using Avalonia.Remote.Protocol.Viewport;
using Avalonia.Threading;
-using Portable.Xaml;
namespace Avalonia.DesignerSupport.Remote
{
@@ -206,7 +205,6 @@ namespace Avalonia.DesignerSupport.Remote
}
catch (Exception e)
{
- var xamlException = e as XamlException;
var xmlException = e as XmlException;
s_transport.Send(new UpdateXamlResultMessage
@@ -216,8 +214,8 @@ namespace Avalonia.DesignerSupport.Remote
{
ExceptionType = e.GetType().FullName,
Message = e.Message.ToString(),
- LineNumber = xamlException?.LineNumber ?? xmlException?.LineNumber,
- LinePosition = xamlException?.LinePosition ?? xmlException?.LinePosition,
+ LineNumber = xmlException?.LineNumber,
+ LinePosition = xmlException?.LinePosition,
}
});
}
diff --git a/src/Avalonia.Themes.Default/TextBox.xaml b/src/Avalonia.Themes.Default/TextBox.xaml
index 9aba2275bf..ec1f6e9e7d 100644
--- a/src/Avalonia.Themes.Default/TextBox.xaml
+++ b/src/Avalonia.Themes.Default/TextBox.xaml
@@ -48,7 +48,8 @@
TextWrapping="{TemplateBinding TextWrapping}"
PasswordChar="{TemplateBinding PasswordChar}"
SelectionBrush="{TemplateBinding SelectionBrush}"
- SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}"/>
+ SelectionForegroundBrush="{TemplateBinding SelectionForegroundBrush}"
+ CaretBrush="{TemplateBinding CaretBrush}"/>
diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
index 8ce29e5b8e..6f3dabd568 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
+++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj
@@ -11,38 +11,22 @@
-
-
-
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -52,7 +36,6 @@
-
@@ -76,11 +59,11 @@
-
+
diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs
deleted file mode 100644
index f967bdf0af..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaTypeConverters.cs
+++ /dev/null
@@ -1,107 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Collections.Generic;
-using System.Globalization;
-using Avalonia.Collections;
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml.Converters;
-using Avalonia.Media.Imaging;
-using Avalonia.Styling;
-using Avalonia.Controls.Templates;
-
-namespace Avalonia.Markup.Xaml
-{
- using System.Reflection;
- using Avalonia.Media;
-
- ///
- /// Maintains a repository of s for XAML parsing on top of those
- /// maintained by .
- ///
- ///
- /// The default method of defining type converters using
- /// isn't powerful enough for our purposes:
- ///
- /// - It doesn't handle non-constructed generic types (such as )
- /// - Type converters which require XAML features cannot be defined in non-XAML assemblies and
- /// so can't be referenced using
- /// - Many types have a static `Parse(string)` method which can be used implicitly; this class
- /// detects such methods and auto-creates a type converter
- ///
- public static class AvaloniaTypeConverters
- {
- // When adding item to that list make sure to modify AvaloniaXamlIlLanguage
- private static Dictionary _converters = new Dictionary()
- {
- { typeof(AvaloniaList<>), typeof(AvaloniaListConverter<>) },
- { typeof(AvaloniaProperty), typeof(AvaloniaPropertyTypeConverter) },
- { typeof(IBitmap), typeof(BitmapTypeConverter) },
- { typeof(IList), typeof(PointsListTypeConverter) },
- { typeof(IMemberSelector), typeof(MemberSelectorTypeConverter) },
- { typeof(Selector), typeof(SelectorTypeConverter) },
- { typeof(TimeSpan), typeof(TimeSpanTypeConverter) },
- { typeof(WindowIcon), typeof(IconTypeConverter) },
- { typeof(CultureInfo), typeof(CultureInfoConverter) },
- { typeof(Uri), typeof(AvaloniaUriTypeConverter) },
- { typeof(FontFamily), typeof(FontFamilyTypeConverter) },
- { typeof(EventInfo), typeof(AvaloniaEventConverter) },
- };
-
- internal static Type GetBuiltinTypeConverter(Type type)
- {
- _converters.TryGetValue(type, out var result);
- return result;
- }
-
- ///
- /// Tries to lookup a for a type.
- ///
- /// The type.
- /// The type converter.
- public static Type GetTypeConverter(Type type)
- {
- if (type.IsConstructedGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>))
- {
- var inner = GetTypeConverter(type.GetGenericArguments()[0]);
- if (inner == null)
- return null;
- return typeof(NullableTypeConverter<>).MakeGenericType(inner);
- }
-
- if (_converters.TryGetValue(type, out var result))
- {
- return result;
- }
-
- // Converters for non-constructed generic types can't be specified using
- // TypeConverterAttribute. Allow them to be registered here and handle them sanely.
- if (type.IsConstructedGenericType &&
- _converters.TryGetValue(type.GetGenericTypeDefinition(), out result))
- {
- return result?.MakeGenericType(type.GetGenericArguments());
- }
-
- // If the type isn't a primitive or a type that XAML already handles, but has a static
- // Parse method, use that
- if (!type.IsPrimitive &&
- type != typeof(DateTime) &&
- type != typeof(Uri) &&
- ParseTypeConverter.HasParseMethod(type))
- {
- result = typeof(ParseTypeConverter<>).MakeGenericType(type);
- _converters.Add(type, result);
- return result;
- }
-
- _converters.Add(type, null);
- return null;
- }
-
- ///
- /// Registers a type converter for a type.
- ///
- /// The type. Maybe be a non-constructed generic type.
- /// The converter type. Maybe be a non-constructed generic type.
- public static void Register(Type type, Type converterType) => _converters[type] = converterType;
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
index 45424e67bb..e8f2439f46 100644
--- a/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/AvaloniaXamlLoader.cs
@@ -15,7 +15,6 @@ using Avalonia.Controls;
using Avalonia.Markup.Data;
using Avalonia.Markup.Xaml.PortableXaml;
using Avalonia.Platform;
-using Portable.Xaml;
namespace Avalonia.Markup.Xaml
{
@@ -26,71 +25,14 @@ namespace Avalonia.Markup.Xaml
{
public bool IsDesignMode { get; set; }
- public static bool UseLegacyXamlLoader { get; set; } = false;
-
- ///
- /// Initializes a new instance of the class.
- ///
- public AvaloniaXamlLoader()
- {
- }
-
///
/// Loads the XAML into a Avalonia component.
///
/// The object to load the XAML into.
public static void Load(object obj)
{
- Contract.Requires(obj != null);
-
- var loader = new AvaloniaXamlLoader();
- loader.Load(obj.GetType(), obj);
- }
-
- ///
- /// Loads the XAML for a type.
- ///
- /// The type.
- ///
- /// The optional instance into which the XAML should be loaded.
- ///
- /// The loaded object.
- public object Load(Type type, object rootInstance = null)
- {
- Contract.Requires(type != null);
-
- // HACK: Currently Visual Studio is forcing us to change the extension of xaml files
- // in certain situations, so we try to load .xaml and if that's not found we try .xaml.
- // Ideally we'd be able to use .xaml everywhere
- var assetLocator = AvaloniaLocator.Current.GetService();
-
- if (assetLocator == null)
- {
- throw new InvalidOperationException(
- "Could not create IAssetLoader : maybe Application.RegisterServices() wasn't called?");
- }
-
- foreach (var uri in GetUrisFor(assetLocator, type))
- {
- if (assetLocator.Exists(uri))
- {
- using (var stream = assetLocator.Open(uri))
- {
- var initialize = rootInstance as ISupportInitialize;
- initialize?.BeginInit();
- try
- {
- return Load(stream, type.Assembly, rootInstance, uri);
- }
- finally
- {
- initialize?.EndInit();
- }
- }
- }
- }
-
- throw new FileNotFoundException("Unable to find view for " + type.FullName);
+ throw new XamlLoadException(
+ $"No precompiled XAML found for {obj.GetType()}, make sure to specify x:Class and include your XAML file as AvaloniaResource");
}
///
@@ -100,11 +42,8 @@ namespace Avalonia.Markup.Xaml
///
/// A base URI to use if is relative.
///
- ///
- /// The optional instance into which the XAML should be loaded.
- ///
/// The loaded object.
- public object Load(Uri uri, Uri baseUri = null, object rootInstance = null)
+ public object Load(Uri uri, Uri baseUri = null)
{
Contract.Requires(uri != null);
@@ -133,7 +72,7 @@ namespace Avalonia.Markup.Xaml
using (var stream = asset.stream)
{
var absoluteUri = uri.IsAbsoluteUri ? uri : new Uri(baseUri, uri);
- return Load(stream, asset.assembly, rootInstance, absoluteUri);
+ return Load(stream, asset.assembly, null, absoluteUri);
}
}
@@ -166,95 +105,9 @@ namespace Avalonia.Markup.Xaml
///
/// The URI of the XAML
/// The loaded object.
- public object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null)
- {
- if (!UseLegacyXamlLoader)
- return AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri, IsDesignMode);
-
-
- var readerSettings = new XamlXmlReaderSettings()
- {
- BaseUri = uri,
- LocalAssembly = localAssembly,
- ProvideLineInfo = true,
- };
-
- var context = IsDesignMode ? AvaloniaXamlSchemaContext.DesignInstance : AvaloniaXamlSchemaContext.Instance;
- var reader = new XamlXmlReader(stream, context, readerSettings);
-
- object result = LoadFromReader(
- reader,
- AvaloniaXamlContext.For(readerSettings, rootInstance));
-
- var topLevel = result as TopLevel;
-
- if (topLevel != null)
- {
- DelayedBinding.ApplyBindings(topLevel);
- }
-
- return result;
- }
-
- internal static object LoadFromReader(XamlReader reader, AvaloniaXamlContext context = null, IAmbientProvider parentAmbientProvider = null)
- {
- var writer = AvaloniaXamlObjectWriter.Create(
- (AvaloniaXamlSchemaContext)reader.SchemaContext,
- context,
- parentAmbientProvider);
+ public object Load(Stream stream, Assembly localAssembly, object rootInstance = null, Uri uri = null)
+ => AvaloniaXamlIlRuntimeCompiler.Load(stream, localAssembly, rootInstance, uri, IsDesignMode);
- XamlServices.Transform(reader, writer);
- writer.ApplyAllDelayedProperties();
- return writer.Result;
- }
-
- internal static object LoadFromReader(XamlReader reader)
- {
- //return XamlServices.Load(reader);
- return LoadFromReader(reader, null);
- }
-
-
- private static readonly DataContractSerializer s_xamlInfoSerializer =
- new DataContractSerializer(typeof(AvaloniaResourceXamlInfo));
- ///
- /// Gets the URI for a type.
- ///
- ///
- /// The type.
- /// The URI.
- private static IEnumerable GetUrisFor(IAssetLoader assetLocator, Type type)
- {
- var asm = type.GetTypeInfo().Assembly.GetName().Name;
- var xamlInfoUri = new Uri($"avares://{asm}/!AvaloniaResourceXamlInfo");
- var typeName = type.FullName;
- if (typeName == null)
- throw new ArgumentException("Type doesn't have a FullName");
-
- if (assetLocator.Exists(xamlInfoUri))
- {
- using (var xamlInfoStream = assetLocator.Open(xamlInfoUri))
- {
- var assetDoc = XDocument.Load(xamlInfoStream);
- XNamespace assetNs = assetDoc.Root.Attribute("xmlns").Value;
- XNamespace arrayNs = "http://schemas.microsoft.com/2003/10/Serialization/Arrays";
- Dictionary xamlInfo =
- assetDoc.Root.Element(assetNs + "ClassToResourcePathIndex").Elements(arrayNs + "KeyValueOfstringstring")
- .ToDictionary(entry =>entry.Element(arrayNs + "Key").Value,
- entry => entry.Element(arrayNs + "Value").Value);
-
- if (xamlInfo.TryGetValue(typeName, out var rv))
- {
- yield return new Uri($"avares://{asm}{rv}");
- yield break;
- }
- }
- }
-
- yield return new Uri("resm:" + typeName + ".xaml?assembly=" + asm);
- yield return new Uri("resm:" + typeName + ".paml?assembly=" + asm);
- }
-
public static object Parse(string xaml, Assembly localAssembly = null)
=> new AvaloniaXamlLoader().Load(xaml, localAssembly);
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaEventConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaEventConverter.cs
deleted file mode 100644
index 665e71bfea..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaEventConverter.cs
+++ /dev/null
@@ -1,99 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Globalization;
-using System.Linq;
-using System.Linq.Expressions;
-using System.Reflection;
-using Avalonia.Controls;
-using Avalonia.Markup.Xaml.PortableXaml;
-using Portable.Xaml;
-
-namespace Avalonia.Markup.Xaml.Converters
-{
- internal class AvaloniaEventConverter : TypeConverter
- {
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- var text = value as string;
- if (text != null)
- {
- var rootObjectProvider = context.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
- var destinationTypeProvider = context.GetService(typeof(IDestinationTypeProvider)) as IDestinationTypeProvider;
- if (rootObjectProvider != null && destinationTypeProvider != null)
- {
- var target = rootObjectProvider.RootObject;
- var eventType = destinationTypeProvider.GetDestinationType();
- var eventParameters = eventType.GetRuntimeMethods().First(r => r.Name == "Invoke").GetParameters();
- // go in reverse to match System.Xaml behaviour
- var methods = target.GetType().GetRuntimeMethods().Reverse();
-
- // find based on exact match parameter types first
- foreach (var method in methods)
- {
- if (method.Name != text)
- continue;
- var parameters = method.GetParameters();
- if (eventParameters.Length != parameters.Length)
- continue;
- if (parameters.Length == 0)
- return method.CreateDelegate(eventType, target);
-
- for (int i = 0; i < parameters.Length; i++)
- {
- var param = parameters[i];
- var eventParam = eventParameters[i];
- if (param.ParameterType != eventParam.ParameterType)
- break;
- if (i == parameters.Length - 1)
- return method.CreateDelegate(eventType, target);
- }
- }
-
- // EnhancedXaml: Find method with compatible base class parameters
- foreach (var method in methods)
- {
- if (method.Name != text)
- continue;
- var parameters = method.GetParameters();
- if (parameters.Length == 0 || eventParameters.Length != parameters.Length)
- continue;
-
- for (int i = 0; i < parameters.Length; i++)
- {
- var param = parameters[i];
- var eventParam = eventParameters[i];
- if (!param.ParameterType.GetTypeInfo().IsAssignableFrom(eventParam.ParameterType.GetTypeInfo()))
- break;
- if (i == parameters.Length - 1)
- return method.CreateDelegate(eventType, target);
- }
- }
-
- var contextProvider = (IXamlSchemaContextProvider)context.GetService(typeof(IXamlSchemaContextProvider));
- var avaloniaContext = (AvaloniaXamlSchemaContext)contextProvider.SchemaContext;
-
- if (avaloniaContext.IsDesignMode)
- {
- // We want to ignore missing events in the designer, so if event handler
- // wasn't found create an empty delegate.
- var lambdaExpression = Expression.Lambda(
- eventType,
- Expression.Empty(),
- eventParameters.Select(x => Expression.Parameter(x.ParameterType)));
- return lambdaExpression.Compile();
- }
- else
- {
- throw new XamlObjectWriterException($"Referenced value method {text} in type {target.GetType()} indicated by event {eventType.FullName} was not found");
- }
- }
- }
- return base.ConvertFrom(context, culture, value);
- }
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
index 18a7fe9ab6..b42bd53619 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Converters/AvaloniaPropertyTypeConverter.cs
@@ -11,7 +11,6 @@ using Avalonia.Markup.Xaml.Parsers;
using Avalonia.Markup.Xaml.Templates;
using Avalonia.Styling;
using Avalonia.Utilities;
-using Portable.Xaml.ComponentModel;
namespace Avalonia.Markup.Xaml.Converters
{
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs
index bfee7b953b..c75c54554e 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Converters/BitmapTypeConverter.cs
@@ -8,8 +8,7 @@ using Avalonia.Platform;
namespace Avalonia.Markup.Xaml.Converters
{
- using Portable.Xaml.ComponentModel;
- using System.ComponentModel;
+ using System.ComponentModel;
public class BitmapTypeConverter : TypeConverter
{
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs
index 863e8fbbce..e92c155773 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Converters/FontFamilyTypeConverter.cs
@@ -7,7 +7,6 @@ using System.Globalization;
using Avalonia.Media;
-using Portable.Xaml.ComponentModel;
namespace Avalonia.Markup.Xaml.Converters
{
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs
index f3972ffe18..3a2f41bd3d 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Converters/IconTypeConverter.cs
@@ -9,7 +9,6 @@ using System.Globalization;
namespace Avalonia.Markup.Xaml.Converters
{
- using Portable.Xaml.ComponentModel;
using System.ComponentModel;
public class IconTypeConverter : TypeConverter
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/NullableTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/NullableTypeConverter.cs
deleted file mode 100644
index 5e7a31da56..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/NullableTypeConverter.cs
+++ /dev/null
@@ -1,89 +0,0 @@
-using System;
-using System.Collections;
-using System.ComponentModel;
-using System.Globalization;
-
-namespace Avalonia.Markup.Xaml.Converters
-{
- public class NullableTypeConverter : TypeConverter where T : TypeConverter, new()
- {
- private TypeConverter _inner;
-
- public NullableTypeConverter()
- {
- _inner = new T();
- }
-
- public NullableTypeConverter(TypeConverter inner)
- {
- _inner = inner;
- }
-
-
- public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
- {
- if (value == null)
- return null;
- return _inner.ConvertTo(context, culture, value, destinationType);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- if (value == null)
- return null;
- if (value as string == "")
- return null;
- return _inner.ConvertFrom(context, culture, value);
- }
-
- public override object CreateInstance(ITypeDescriptorContext context, IDictionary propertyValues)
- {
- return _inner.CreateInstance(context, propertyValues);
- }
-
- public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
- {
- return _inner.GetStandardValuesSupported(context);
- }
-
- public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
- {
- return _inner.GetStandardValuesExclusive(context);
- }
-
- public override bool GetCreateInstanceSupported(ITypeDescriptorContext context)
- {
- return _inner.GetCreateInstanceSupported(context);
- }
-
- public override bool GetPropertiesSupported(ITypeDescriptorContext context)
- {
- return _inner.GetPropertiesSupported(context);
- }
-
- public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
- {
- return _inner.GetStandardValues(context);
- }
-
- public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
- {
- return _inner.GetProperties(context, value, attributes);
- }
-
- public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
- {
- return _inner.CanConvertTo(context, destinationType);
- }
-
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- return _inner.CanConvertFrom(context, sourceType);
- }
-
- public override bool IsValid(ITypeDescriptorContext context, object value)
- {
- return _inner.IsValid(context, value);
- }
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/ParseTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/ParseTypeConverter.cs
deleted file mode 100644
index bfb446fa15..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/ParseTypeConverter.cs
+++ /dev/null
@@ -1,79 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Globalization;
-using System.Reflection;
-
-namespace Avalonia.Markup.Xaml.Converters
-{
- ///
- /// Base class for type converters which call a static Parse method.
- ///
- public abstract class ParseTypeConverter : TypeConverter
- {
- protected const BindingFlags PublicStatic = BindingFlags.Public | BindingFlags.Static;
- protected static readonly Type[] StringParameter = new[] { typeof(string) };
- protected static readonly Type[] StringIFormatProviderParameters = new[] { typeof(string), typeof(IFormatProvider) };
-
- ///
- /// Checks whether a type has a suitable Parse method.
- ///
- /// The type.
- /// True if the type has a suitable parse method, otherwise false.
- public static bool HasParseMethod(Type type)
- {
- return type.GetMethod("Parse", PublicStatic, null, StringIFormatProviderParameters, null) != null ||
- type.GetMethod("Parse", PublicStatic, null, StringParameter, null) != null;
- }
- }
-
- ///
- /// A type converter which calls a static Parse method.
- ///
- /// The type with the Parse method.
- public class ParseTypeConverter : ParseTypeConverter
- {
- private static Func _parse;
- private static Func _parseWithFormat;
-
- static ParseTypeConverter()
- {
- var method = typeof(T).GetMethod("Parse", PublicStatic, null, StringIFormatProviderParameters, null);
-
- if (method != null)
- {
- _parseWithFormat = (Func)method
- .CreateDelegate(typeof(Func));
- return;
- }
-
- method = typeof(T).GetMethod("Parse", PublicStatic, null, StringParameter, null);
-
- if (method != null)
- {
- _parse = (Func)method.CreateDelegate(typeof(Func));
- }
- }
-
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- return sourceType == typeof(string);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- if (value != null)
- {
- if (_parse != null)
- {
- return _parse(value.ToString());
- }
- else if (_parseWithFormat != null)
- {
- return _parseWithFormat(value.ToString(), culture);
- }
- }
-
- return null;
- }
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/SelectorTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/SelectorTypeConverter.cs
deleted file mode 100644
index 54234fe406..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/SelectorTypeConverter.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) The Avalonia 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 Avalonia.Markup.Parsers;
-
-namespace Avalonia.Markup.Xaml.Converters
-{
- using Portable.Xaml.ComponentModel;
- using System.ComponentModel;
-
- public class SelectorTypeConverter : TypeConverter
- {
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- return sourceType == typeof(string);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- var parser = new SelectorParser(context.ResolveType);
-
- return parser.Parse((string)value);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/Converters/SetterValueTypeConverter.cs b/src/Markup/Avalonia.Markup.Xaml/Converters/SetterValueTypeConverter.cs
deleted file mode 100644
index 81cda6db1f..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/Converters/SetterValueTypeConverter.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright (c) The Avalonia Project. All rights reserved.
-// Licensed under the MIT license. See licence.md file in the project root for full license information.
-
-using Avalonia.Styling;
-using Portable.Xaml;
-using Portable.Xaml.ComponentModel;
-using System.ComponentModel;
-using Portable.Xaml.Markup;
-using System;
-using System.Globalization;
-
-namespace Avalonia.Markup.Xaml.Converters
-{
- public class SetterValueTypeConverter : TypeConverter
- {
- public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
- {
- return sourceType == typeof(string);
- }
-
- public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
- {
- object setter = context.GetService().TargetObject;
- var schemaContext = context.GetService().SchemaContext;
-
- return ConvertSetterValue(context, schemaContext, culture, (setter as Setter), value);
- }
-
- [Obsolete("TODO: try assosiate Setter.Value property with SetterValueTypeConverter, so far coouldn't make it :(")]
- internal static object ConvertSetterValue(ITypeDescriptorContext dcontext, XamlSchemaContext context, CultureInfo info, Setter setter, object value)
- {
- Type targetType = setter?.Property?.PropertyType;
-
- if (targetType == null)
- {
- return value;
- }
-
- var ttConv = context.GetXamlType(targetType)?.TypeConverter?.ConverterInstance;
-
- if (ttConv != null)
- {
- value = ttConv.ConvertFromString(dcontext, info, value as string);
- }
-
- return value;
- }
- }
-}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/Extensions.cs b/src/Markup/Avalonia.Markup.Xaml/Extensions.cs
index c6b914ba72..fe3fd44c1c 100644
--- a/src/Markup/Avalonia.Markup.Xaml/Extensions.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/Extensions.cs
@@ -3,8 +3,6 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using Avalonia.Markup.Xaml.XamlIl.Runtime;
-using Portable.Xaml;
-using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml
{
@@ -13,42 +11,19 @@ namespace Avalonia.Markup.Xaml
public static T GetService(this IServiceProvider sp) => (T)sp?.GetService(typeof(T));
- public static Uri GetContextBaseUri(this IServiceProvider ctx)
- {
- var properService = ctx.GetService();
- if (properService != null)
- return properService.BaseUri;
- // Ugly hack with casts
- return Portable.Xaml.ComponentModel.TypeDescriptorExtensions.GetBaseUri((ITypeDescriptorContext)ctx);
- }
+ public static Uri GetContextBaseUri(this IServiceProvider ctx) => ctx.GetService().BaseUri;
- public static T GetFirstParent(this IServiceProvider ctx) where T : class
- {
- var parentStack = ctx.GetService();
- if (parentStack != null)
- return parentStack.Parents.OfType().FirstOrDefault();
- return Portable.Xaml.ComponentModel.TypeDescriptorExtensions.GetFirstAmbientValue((ITypeDescriptorContext)ctx);
- }
-
- public static T GetLastParent(this IServiceProvider ctx) where T : class
- {
- var parentStack = ctx.GetService();
- if (parentStack != null)
- return parentStack.Parents.OfType().LastOrDefault();
- return Portable.Xaml.ComponentModel.TypeDescriptorExtensions.GetLastOrDefaultAmbientValue(
- (ITypeDescriptorContext)ctx);
- }
+ public static T GetFirstParent(this IServiceProvider ctx) where T : class
+ => ctx.GetService().Parents.OfType().FirstOrDefault();
+
+ public static T GetLastParent(this IServiceProvider ctx) where T : class
+ => ctx.GetService().Parents.OfType().LastOrDefault();
public static IEnumerable GetParents(this IServiceProvider sp)
{
- var stack = sp.GetService();
- if (stack != null)
- return stack.Parents.OfType();
+ return sp.GetService().Parents.OfType();
+
- var context = (ITypeDescriptorContext)sp;
- var schemaContext = context.GetService().SchemaContext;
- var ambientProvider = context.GetService();
- return ambientProvider.GetAllAmbientValues(schemaContext.GetXamlType(typeof(T))).OfType();
}
public static Type ResolveType(this IServiceProvider ctx, string namespacePrefix, string type)
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtension.cs
new file mode 100644
index 0000000000..858f2daa58
--- /dev/null
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtension.cs
@@ -0,0 +1,9 @@
+using System;
+
+namespace Avalonia.Markup.Xaml
+{
+ public abstract class MarkupExtension
+ {
+ public abstract object ProvideValue(IServiceProvider serviceProvider);
+ }
+}
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs
index 223716ae3b..726f4221f8 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/BindingExtension.cs
@@ -10,14 +10,9 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
using Avalonia.Data.Converters;
using Avalonia.Markup.Data;
using Avalonia.Styling;
- using Portable.Xaml;
- using Portable.Xaml.ComponentModel;
- using Portable.Xaml.Markup;
- using PortableXaml;
using System.ComponentModel;
- [MarkupExtensionReturnType(typeof(IBinding))]
- public class BindingExtension : MarkupExtension
+ public class BindingExtension
{
public BindingExtension()
{
@@ -28,12 +23,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Path = path;
}
- public override object ProvideValue(IServiceProvider serviceProvider)
- {
- return ProvideTypedValue(serviceProvider);
- }
-
- public Binding ProvideTypedValue(IServiceProvider serviceProvider)
+ public Binding ProvideValue(IServiceProvider serviceProvider)
{
var descriptorContext = (ITypeDescriptorContext)serviceProvider;
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs
index 48e55dc251..0a9289bec9 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/DynamicResourceExtension.cs
@@ -7,13 +7,10 @@ using System.Linq;
using System.Reactive.Linq;
using Avalonia.Controls;
using Avalonia.Data;
-using Portable.Xaml;
-using Portable.Xaml.ComponentModel;
-using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
- public class DynamicResourceExtension : MarkupExtension, IBinding
+ public class DynamicResourceExtension : IBinding
{
private IResourceNode _anchor;
@@ -28,9 +25,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public object ResourceKey { get; set; }
- public override object ProvideValue(IServiceProvider serviceProvider) => ProvideTypedValue(serviceProvider);
-
- public IBinding ProvideTypedValue(IServiceProvider serviceProvider)
+ public IBinding ProvideValue(IServiceProvider serviceProvider)
{
var provideTarget = serviceProvider.GetService();
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/RelativeSourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/RelativeSourceExtension.cs
index 2f7256fa22..f690a5ff0e 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/RelativeSourceExtension.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/RelativeSourceExtension.cs
@@ -3,11 +3,10 @@
using System;
using Avalonia.Data;
-using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
- public class RelativeSourceExtension : MarkupExtension
+ public class RelativeSourceExtension
{
public RelativeSourceExtension()
{
@@ -18,7 +17,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
Mode = mode;
}
- public override object ProvideValue(IServiceProvider serviceProvider)
+ public RelativeSource ProvideValue(IServiceProvider serviceProvider)
{
return new RelativeSource
{
@@ -38,4 +37,4 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public int AncestorLevel { get; set; } = 1;
}
-}
\ No newline at end of file
+}
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
index 323a341f6a..3525628a79 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/ResourceInclude.cs
@@ -1,15 +1,13 @@
using System;
using System.ComponentModel;
using Avalonia.Controls;
-using Portable.Xaml.ComponentModel;
-using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
///
/// Loads a resource dictionary from a specified URL.
///
- public class ResourceInclude : MarkupExtension, IResourceProvider
+ public class ResourceInclude :IResourceProvider
{
private Uri _baseUri;
private IResourceDictionary _loaded;
@@ -52,13 +50,7 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
return Loaded.TryGetResource(key, out value);
}
- ///
- public override object ProvideValue(IServiceProvider serviceProvider)
- {
- return ProvideTypedValue(serviceProvider);
- }
-
- public ResourceInclude ProvideTypedValue(IServiceProvider serviceProvider)
+ public ResourceInclude ProvideValue(IServiceProvider serviceProvider)
{
var tdc = (ITypeDescriptorContext)serviceProvider;
_baseUri = tdc?.GetContextBaseUri();
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
index ea913db598..d6b170ae9d 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StaticResourceExtension.cs
@@ -7,13 +7,10 @@ using System.ComponentModel;
using System.Reflection;
using Avalonia.Controls;
using Avalonia.Markup.Data;
-using Portable.Xaml;
-using Portable.Xaml.ComponentModel;
-using Portable.Xaml.Markup;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
- public class StaticResourceExtension : MarkupExtension
+ public class StaticResourceExtension
{
public StaticResourceExtension()
{
@@ -26,26 +23,13 @@ namespace Avalonia.Markup.Xaml.MarkupExtensions
public string ResourceKey { get; set; }
- public override object ProvideValue(IServiceProvider serviceProvider)
+ public object ProvideValue(IServiceProvider serviceProvider)
{
-
-
// Look upwards though the ambient context for IResourceProviders which might be able
// to give us the resource.
foreach (var resourceProvider in serviceProvider.GetParents())
{
- // We override XamlType.CanAssignTo in BindingXamlType so the results we get back
- // from GetAllAmbientValues aren't necessarily of the correct type.
-
- if (AvaloniaXamlLoader.UseLegacyXamlLoader
- && resourceProvider is IControl control && control.StylingParent != null)
- {
- // If we've got to a control that has a StylingParent then it's probably
- // a top level control and its StylingParent is pointing to the global
- // styles. If this is case just do a FindResource on it.
- return control.FindResource(ResourceKey);
- }
- else if (resourceProvider.TryGetResource(ResourceKey, out var value))
+ if (resourceProvider.TryGetResource(ResourceKey, out var value))
{
return value;
}
diff --git a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs
index d9345738fc..a323050c31 100644
--- a/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs
+++ b/src/Markup/Avalonia.Markup.Xaml/MarkupExtensions/StyleIncludeExtension.cs
@@ -3,23 +3,18 @@
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Styling;
-using Portable.Xaml;
-using Portable.Xaml.ComponentModel;
using System.ComponentModel;
-using Portable.Xaml.Markup;
using System;
namespace Avalonia.Markup.Xaml.MarkupExtensions
{
- [MarkupExtensionReturnType(typeof(IStyle))]
- public class StyleIncludeExtension : MarkupExtension
+ public class StyleIncludeExtension
{
public StyleIncludeExtension()
{
}
- public override object ProvideValue(IServiceProvider serviceProvider) => ProvideTypedValue(serviceProvider);
- public IStyle ProvideTypedValue(IServiceProvider serviceProvider)
+ public IStyle ProvideValue(IServiceProvider serviceProvider)
{
return new StyleInclude(serviceProvider.GetContextBaseUri()) { Source = Source };
}
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AttributeExtensions.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AttributeExtensions.cs
deleted file mode 100644
index 2a23b7e068..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AttributeExtensions.cs
+++ /dev/null
@@ -1,39 +0,0 @@
-using Avalonia.Markup.Xaml.Templates;
-using avm = Avalonia.Metadata;
-using pm = Portable.Xaml.Markup;
-
-namespace Avalonia.Markup.Xaml.PortableXaml
-{
- internal static class AttributeExtensions
- {
- public static pm.XamlDeferLoadAttribute ToPortableXaml(this avm.TemplateContentAttribute attrib)
- {
- if (attrib == null)
- {
- return null;
- }
-
- return new pm.XamlDeferLoadAttribute(typeof(TemplateLoader), typeof(TemplateContent));
- }
-
- public static pm.AmbientAttribute ToPortableXaml(this avm.AmbientAttribute attrib)
- {
- if (attrib == null)
- {
- return null;
- }
-
- return new pm.AmbientAttribute();
- }
-
- public static pm.DependsOnAttribute ToPortableXaml(this avm.DependsOnAttribute attrib)
- {
- if (attrib == null)
- {
- return null;
- }
-
- return new pm.DependsOnAttribute(attrib.Name);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaMemberAttributeProvider.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaMemberAttributeProvider.cs
deleted file mode 100644
index 529cbab938..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaMemberAttributeProvider.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-using Avalonia.Markup.Xaml.Converters;
-using Avalonia.Styling;
-using Portable.Xaml.ComponentModel;
-using System.ComponentModel;
-using System;
-using System.Linq;
-using System.Reflection;
-using avm = Avalonia.Metadata;
-using pm = Portable.Xaml.Markup;
-
-namespace Avalonia.Markup.Xaml.PortableXaml
-{
- public class AvaloniaMemberAttributeProvider : ICustomAttributeProvider
- {
- public AvaloniaMemberAttributeProvider(MemberInfo info)
- {
- _info = info;
- }
-
- public object[] GetCustomAttributes(bool inherit)
- {
- throw new NotImplementedException();
- }
-
- public object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- Attribute result = null;
-
- if (attributeType == typeof(pm.XamlDeferLoadAttribute))
- {
- result = _info.GetCustomAttribute(inherit)
- .ToPortableXaml();
- }
- else if (attributeType == typeof(pm.AmbientAttribute))
- {
- result = _info.GetCustomAttribute(inherit)
- .ToPortableXaml();
- }
- else if (attributeType == typeof(pm.DependsOnAttribute))
- {
- result = _info.GetCustomAttribute(inherit)
- .ToPortableXaml();
- }
- else if (attributeType == typeof(TypeConverterAttribute) &&
- _info.DeclaringType == typeof(Setter) &&
- _info.Name == nameof(Setter.Value))
- {
- //actually it never comes here looks like if property type is object
- //Portable.Xaml is not searching for Type Converter
- result = new TypeConverterAttribute(typeof(SetterValueTypeConverter));
- }
- else if (attributeType == typeof(TypeConverterAttribute) && _info is EventInfo)
- {
- // If a type converter for `EventInfo` is registered, then use that to convert
- // event handler values. This is used by the designer to override the lookup
- // for event handlers with a null handler.
- var eventConverter = AvaloniaTypeConverters.GetTypeConverter(typeof(EventInfo));
-
- if (eventConverter != null)
- {
- result = new TypeConverterAttribute(eventConverter);
- }
- }
-
- if (result == null)
- {
- var attr = _info.GetCustomAttributes(attributeType, inherit);
- return (attr as object[]) ?? attr.ToArray();
- }
- else
- {
- return new object[] { result };
- }
- }
-
- public bool IsDefined(Type attributeType, bool inherit)
- {
- throw new NotImplementedException();
- }
-
- private readonly MemberInfo _info;
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaNameScope.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaNameScope.cs
deleted file mode 100644
index 6f855bafa1..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaNameScope.cs
+++ /dev/null
@@ -1,56 +0,0 @@
-using System.Collections.Generic;
-using Avalonia.Controls;
-
-namespace Avalonia.Markup.Xaml.PortableXaml
-{
- internal class AvaloniaNameScope : Portable.Xaml.Markup.INameScope
- {
- public object Instance { get; set; }
-
- private Dictionary _names = new Dictionary();
-
- public object FindName(string name)
- {
- object result;
- if (_names.TryGetValue(name, out result))
- return result;
- return null;
- }
-
- public void RegisterName(string name, object scopedElement)
- {
- if (scopedElement != null)
- _names.Add(name, scopedElement);
-
- //TODO: ???
- //var control = scopedElement as Control;
-
- //if (control != null)
- //{
- // var nameScope = (Instance as INameScope) ?? control.FindNameScope();
-
- // if (nameScope != null)
- // {
- // nameScope.Register(name, scopedElement);
- // }
- //}
- }
-
- public void UnregisterName(string name)
- {
- }
-
- public void RegisterOnNameScope(object target)
- {
- var nameScope = target as INameScope;
-
- if (nameScope != null)
- {
- foreach (var v in _names)
- {
- nameScope.Register(v.Key, v.Value);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaRuntimeTypeProvider.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaRuntimeTypeProvider.cs
deleted file mode 100644
index eb52e317b8..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaRuntimeTypeProvider.cs
+++ /dev/null
@@ -1,147 +0,0 @@
-// Copyright (c) The Avalonia 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.Linq;
-using System.Reflection;
-using Avalonia.Controls;
-using Avalonia.Data;
-using Avalonia.Markup.Xaml.Templates;
-using Avalonia.Media;
-using Avalonia.Metadata;
-using Avalonia.Platform;
-using Avalonia.Styling;
-
-namespace Avalonia.Markup.Xaml.Context
-{
- using ClrNamespaceInfo = Tuple;
-
- public interface IRuntimeTypeProvider
- {
- Type FindType(string xamlNamespace, string name, Type[] genArgs);
-
- IEnumerable ReferencedAssemblies { get; }
- }
-
- public class AvaloniaRuntimeTypeProvider : IRuntimeTypeProvider
- {
- private const string ClrNamespace = "clr-namespace:";
- // private const string AvaloniaNs = "https://github.com/avaloniaui";
-
- private static readonly IEnumerable ForcedAssemblies = new[]
- {
- typeof(AvaloniaObject).GetTypeInfo().Assembly,
- typeof(Animation.Animation).GetTypeInfo().Assembly,
- typeof(Control).GetTypeInfo().Assembly,
- typeof(Style).GetTypeInfo().Assembly,
- typeof(DataTemplate).GetTypeInfo().Assembly,
- typeof(SolidColorBrush).GetTypeInfo().Assembly,
- typeof(Binding).GetTypeInfo().Assembly,
- };
-
- private Dictionary> _namespaces = new Dictionary>();
-
- private List _scanned = new List();
-
- public IEnumerable ReferencedAssemblies => _scanned;
-
- public AvaloniaRuntimeTypeProvider()
- {
- ScanAssemblies(ForcedAssemblies);
- ScanNewAssemblies();
- }
-
- private static bool IsClrNamespace(string ns)
- {
- return ns.StartsWith(ClrNamespace);
- }
-
- private static Assembly GetAssembly(string assemblyName)
- {
- return Assembly.Load(new AssemblyName(assemblyName));
- }
-
- private void ScanAssemblies(IEnumerable assemblies)
- {
- foreach (var assembly in assemblies)
- {
- var namespaces = assembly.GetCustomAttributes()
- .Select(x => new { x.XmlNamespace, x.ClrNamespace })
- .GroupBy(x => x.XmlNamespace);
-
- foreach (var nsa in namespaces)
- {
- HashSet reg;
-
- if (!_namespaces.TryGetValue(nsa.Key, out reg))
- {
- _namespaces[nsa.Key] = reg = new HashSet>();
- }
-
- foreach (var child in nsa)
- {
- reg.Add(new ClrNamespaceInfo(child.ClrNamespace, assembly));
- }
- }
-
- _scanned.Add(assembly);
- }
- }
-
- private void ScanNewAssemblies()
- {
- IEnumerable assemblies = AppDomain.CurrentDomain.GetAssemblies();
-
- if (assemblies != null)
- {
- assemblies = assemblies.Except(_scanned);
- ScanAssemblies(assemblies);
- }
- }
-
- private Dictionary _typeCache = new Dictionary();
-
- public Type FindType(string xamlNamespace, string name, Type[] genArgs)
- {
- if (IsClrNamespace(xamlNamespace))
- {
- //we need to handle only xaml url namespaces for avalonia,
- //the other namespaces are handled well in portable.xaml
- return null;
- }
-
- string key = $"{xamlNamespace}:{name}";
-
- Type type;
-
- if (_typeCache.TryGetValue(key, out type))
- {
- return type;
- }
-
- HashSet reg;
-
- if (!_namespaces.TryGetValue(xamlNamespace, out reg))
- {
- return null;
- }
-
- if (genArgs != null)
- name += "`" + genArgs.Length;
-
- foreach (var ns in reg)
- {
- var n = ns.Item1 + "." + name;
- var t = ns.Item2.GetType(n);
- if (t != null)
- {
- _typeCache[key] = t;
- return t;
- }
- }
-
- return null;
- }
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaTypeAttributeProvider.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaTypeAttributeProvider.cs
deleted file mode 100644
index 7558a5df0b..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaTypeAttributeProvider.cs
+++ /dev/null
@@ -1,117 +0,0 @@
-// 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 Portable.Xaml.ComponentModel;
-using System.ComponentModel;
-using System;
-using System.Linq;
-using System.Reflection;
-using avm = Avalonia.Metadata;
-using pm = Portable.Xaml.Markup;
-
-namespace Avalonia.Markup.Xaml.PortableXaml
-{
- internal class AvaloniaTypeAttributeProvider : ICustomAttributeProvider
- {
- public AvaloniaTypeAttributeProvider(Type type)
- {
- _type = type;
- }
-
- public object[] GetCustomAttributes(bool inherit)
- {
- throw new NotImplementedException();
- }
-
- public object[] GetCustomAttributes(Type attributeType, bool inherit)
- {
- Attribute result = null;
-
- var ti = _type.GetTypeInfo();
-
- if (attributeType == typeof(pm.ContentPropertyAttribute))
- {
- result = GetContentPropertyAttribute(inherit);
- }
- else if (attributeType == typeof(pm.RuntimeNamePropertyAttribute))
- {
- if (_namedType.IsAssignableFrom(ti))
- {
- result = new pm.RuntimeNamePropertyAttribute(nameof(INamed.Name));
- }
- }
- else if (attributeType == typeof(TypeConverterAttribute))
- {
- var builtin = AvaloniaTypeConverters.GetBuiltinTypeConverter(_type);
- if (builtin != null)
- result = new TypeConverterAttribute(builtin);
- result = result ?? ti.GetCustomAttribute(attributeType, inherit);
-
- if (result == null)
- {
- var convType = AvaloniaTypeConverters.GetTypeConverter(_type);
-
- if (convType != null)
- {
- result = new TypeConverterAttribute(convType);
- }
- }
- }
- else if (attributeType == typeof(pm.AmbientAttribute))
- {
- result = ti.GetCustomAttribute(inherit)
- .ToPortableXaml();
- }
-
- if (result == null)
- {
- var attr = ti.GetCustomAttributes(attributeType, inherit);
- return (attr as object[]) ?? attr.ToArray();
- }
- else
- {
- return new object[] { result };
- }
- }
-
- public bool IsDefined(Type attributeType, bool inherit)
- {
- throw new NotImplementedException();
- }
-
- private readonly TypeInfo _namedType = typeof(INamed).GetTypeInfo();
-
- private readonly Type _type;
-
- private Attribute GetContentPropertyAttribute(bool inherit)
- {
- var type = _type;
-
- while (type != null)
- {
- var properties = type.GetTypeInfo().DeclaredProperties
- .Where(x => x.GetCustomAttribute() != null);
- string result = null;
-
- foreach (var property in properties)
- {
- if (result != null)
- {
- throw new Exception($"Content property defined more than once on {type}.");
- }
-
- result = property.Name;
- }
-
- if (result != null)
- {
- return new pm.ContentPropertyAttribute(result);
- }
-
- type = inherit ? type.GetTypeInfo().BaseType : null;
- }
-
- return null;
- }
- }
-}
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlContext.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlContext.cs
deleted file mode 100644
index c159b551b7..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlContext.cs
+++ /dev/null
@@ -1,31 +0,0 @@
-using Portable.Xaml;
-using Portable.Xaml.Markup;
-using System;
-using System.Reflection;
-
-namespace Avalonia.Markup.Xaml.PortableXaml
-{
- public class AvaloniaXamlContext : IUriContext
- {
- private AvaloniaXamlContext()
- {
- }
-
- public Assembly LocalAssembly { get; private set; }
-
- public Uri BaseUri { get; set; }
-
- public object RootInstance { get; private set; }
-
- internal static AvaloniaXamlContext For(XamlXmlReaderSettings sett,
- object rootInstance)
- {
- return new AvaloniaXamlContext()
- {
- BaseUri = sett.BaseUri,
- LocalAssembly = sett.LocalAssembly,
- RootInstance = rootInstance
- };
- }
- }
-}
\ No newline at end of file
diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs
deleted file mode 100644
index 9fa6c26c35..0000000000
--- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/AvaloniaXamlObjectWriter.cs
+++ /dev/null
@@ -1,222 +0,0 @@
-using Avalonia.Data;
-using Portable.Xaml;
-using Portable.Xaml.ComponentModel;
-using System.ComponentModel;
-using System.Collections.Generic;
-using System.Linq;
-using System.Reflection;
-using Avalonia.Controls;
-using Portable.Xaml.Schema;
-
-namespace Avalonia.Markup.Xaml.PortableXaml
-{
- class AvaloniaXamlObjectWriter : XamlObjectWriter
- {
- private static Dictionary DesignDirectives = new Dictionary
- {
- ["DataContext"] = "DataContext",
- ["DesignWidth"] = "Width", ["DesignHeight"] = "Height", ["PreviewWith"] = "PreviewWith"
- }
- .ToDictionary(p => new XamlDirective(
- new[] {"http://schemas.microsoft.com/expression/blend/2008"}, p.Key,
- XamlLanguage.Object, null, AllowedMemberLocations.Attribute), p => p.Value);
-
- private readonly AvaloniaXamlSchemaContext _schemaContext;
-
- public static AvaloniaXamlObjectWriter Create(
- AvaloniaXamlSchemaContext schemaContext,
- AvaloniaXamlContext context,
- IAmbientProvider parentAmbientProvider = null)
- {
- var nameScope = new AvaloniaNameScope { Instance = context?.RootInstance };
-
- var writerSettings = new XamlObjectWriterSettings()
- {
- ExternalNameScope = nameScope,
- RegisterNamesOnExternalNamescope = true,
- RootObjectInstance = context?.RootInstance
- };
-
- return new AvaloniaXamlObjectWriter(schemaContext,
- writerSettings.WithContext(context),
- nameScope,
- parentAmbientProvider);
- }
-
- private readonly DelayedValuesHelper _delayedValuesHelper = new DelayedValuesHelper();
-
- private AvaloniaNameScope _nameScope;
-
- private AvaloniaXamlObjectWriter(
- AvaloniaXamlSchemaContext schemaContext,
- XamlObjectWriterSettings settings,
- AvaloniaNameScope nameScope,
- IAmbientProvider parentAmbientProvider)
- : base(schemaContext, settings, parentAmbientProvider)
- {
- _nameScope = nameScope;
- _schemaContext = schemaContext;
- }
-
- protected override void Dispose(bool disposing)
- {
- if (disposing)
- {
- if (_nameScope != null && Result != null)
- {
- _nameScope.RegisterOnNameScope(Result);
- }
- }
-
- base.Dispose(disposing);
- }
-
- public void ApplyAllDelayedProperties()
- {
- //HACK: We need this because Begin/EndInit ordering is broken
- _delayedValuesHelper.ApplyAll();
- }
-
- protected internal override void OnAfterProperties(object value)
- {
- _delayedValuesHelper.EndInit(value);
-
- base.OnAfterProperties(value);
- }
-
- protected internal override void OnBeforeProperties(object value)
- {
- if (value != null)
- _delayedValuesHelper.BeginInit(value);
-
- base.OnBeforeProperties(value);
- }
-
- protected internal override bool OnSetValue(object target, XamlMember member, object value)
- {
- if (_delayedValuesHelper.TryAdd(target, member, value))
- {
- return true;
- }
-
- return base.OnSetValue(target, member, value);
- }
-
- public override void WriteStartMember(XamlMember property)
- {
- foreach(var d in DesignDirectives)
- if (property == d.Key && _schemaContext.IsDesignMode)
- {
- base.WriteStartMember(new XamlMember(d.Value,
- typeof(Design).GetMethod("Get" + d.Value, BindingFlags.Static | BindingFlags.Public),
- typeof(Design).GetMethod("Set" + d.Value, BindingFlags.Static | BindingFlags.Public),
- SchemaContext));
- return;
- }
- base.WriteStartMember(property);
- }
-
- private class DelayedValuesHelper
- {
- private int _cnt;
-
- private HashSet
-
+
diff --git a/tests/Avalonia.DesignerSupport.TestApp/MainWindow.xaml b/tests/Avalonia.DesignerSupport.TestApp/MainWindow.xaml
index 6938bd8c49..f90e5beaa6 100644
--- a/tests/Avalonia.DesignerSupport.TestApp/MainWindow.xaml
+++ b/tests/Avalonia.DesignerSupport.TestApp/MainWindow.xaml
@@ -1,5 +1,7 @@
+ Title="TESTAPP"
+ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+ x:Class="Avalonia.DesignerSupport.TestApp.MainWindow">
-
\ No newline at end of file
+
diff --git a/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs
index a01bbe0845..01fa0e7783 100644
--- a/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs
+++ b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs
@@ -118,10 +118,21 @@ namespace Avalonia.DesignerSupport.Tests
cancelled = true;
}
- Assert.True(cancelled, $"Message Not Received.");
- Assert.NotEqual(0, handle);
- proc.Kill();
+ try
+ {
+ proc.Kill();
+ }
+ catch
+ {
+ //
+ }
+
proc.WaitForExit();
+ Assert.True(cancelled,
+ $"Message Not Received.\n" + proc.StandardOutput.ReadToEnd() + "\n" +
+ proc.StandardError.ReadToEnd());
+ Assert.NotEqual(0, handle);
+
}
}
}
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/AvaloniaPropertyConverterTest.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/AvaloniaPropertyConverterTest.cs
index f6f56231bc..d82300b964 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Converters/AvaloniaPropertyConverterTest.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Converters/AvaloniaPropertyConverterTest.cs
@@ -8,9 +8,7 @@ using Avalonia.Markup.Xaml.Converters;
using Avalonia.Styling;
using Xunit;
using System.ComponentModel;
-using Portable.Xaml;
-using Portable.Xaml.Markup;
-using Avalonia.Controls;
+using Avalonia.Markup.Xaml.XamlIl.Runtime;
namespace Avalonia.Markup.Xaml.UnitTests.Converters
{
@@ -91,27 +89,23 @@ namespace Avalonia.Markup.Xaml.UnitTests.Converters
Assert.Equal("Could not find property 'AttachedOwner.NonExistent'.", ex.Message);
}
+
+
private ITypeDescriptorContext CreateContext(Style style = null)
{
var tdMock = new Mock();
- var xsc = new Mock();
- var sc = Mock.Of();
- var amb = new Mock();
var tr = new Mock();
+ var ps = new Mock();
- tdMock.Setup(d => d.GetService(typeof(IAmbientProvider)))
- .Returns(amb.Object);
- tdMock.Setup(d => d.GetService(typeof(IXamlSchemaContextProvider)))
- .Returns(xsc.Object);
tdMock.Setup(d => d.GetService(typeof(IXamlTypeResolver)))
.Returns(tr.Object);
- xsc.SetupGet(v => v.SchemaContext)
- .Returns(sc);
- amb.Setup(v => v.GetFirstAmbientValue(It.IsAny()))
- .Returns(style);
- amb.Setup(v => v.GetAllAmbientValues(It.IsAny()))
- .Returns(new object[] { style });
+ tdMock.Setup(d => d.GetService(typeof(IAvaloniaXamlIlParentStackProvider)))
+ .Returns(ps.Object);
+
+ ps.SetupGet(v => v.Parents)
+ .Returns(new object[] {style});
+
tr.Setup(v => v.Resolve(nameof(Class1)))
.Returns(typeof(Class1));
tr.Setup(v => v.Resolve(nameof(AttachedOwner)))
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
index 359d2521e0..7fe0fc4a08 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
@@ -14,7 +14,6 @@ using Avalonia.Media;
using Avalonia.Media.Immutable;
using Avalonia.Styling;
using Avalonia.UnitTests;
-using Portable.Xaml;
using System.Collections;
using System.ComponentModel;
using System.Linq;
@@ -47,37 +46,6 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.Equal("Foo", target.Content);
}
- [Fact]
- public void AvaloniaProperty_Without_Getter_And_Setter_Is_Set()
- {
- // It's not possible to know in compile time if a read-only property has a magic way of being not read-only
- if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
- return;
- var xaml =
- @"";
-
- var target = AvaloniaXamlLoader.Parse(xaml);
-
- Assert.Equal(55, target.GetValue(NonControl.FooProperty));
- }
-
- [Fact]
- public void AvaloniaProperty_With_Getter_And_No_Setter_Is_Set()
- {
- if(!AvaloniaXamlLoader.UseLegacyXamlLoader)
- return;
- var xaml =
-@"";
-
- var target = AvaloniaXamlLoader.Parse(xaml);
-
- Assert.Equal("bar", target.Bar);
- }
-
[Fact]
public void Attached_Property_Is_Set()
{
@@ -159,19 +127,6 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
XamlTestHelpers.AssertThrowsXamlException(() => AvaloniaXamlLoader.Parse(xaml));
}
- [Fact]
- public void Non_Attached_Property_With_Attached_Property_Syntax_Throws()
- {
- // 1) It has been allowed in AvaloniaObject.SetValue for ages
- // 2) There is no way to know if AddOwner was called in compile-time
- if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
- return;
- var xaml =
- @"";
-
- XamlTestHelpers.AssertThrowsXamlException(() => AvaloniaXamlLoader.Parse(xaml));
- }
-
[Fact]
public void ContentControl_ContentTemplate_Is_Functional()
{
@@ -595,31 +550,6 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
}
}
- [Fact]
- public void Xaml_Binding_Is_Delayed()
- {
- if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
- return;
-
- using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
- {
- var xaml =
-@"";
-
- var target = AvaloniaXamlLoader.Parse(xaml);
-
- Assert.Null(target.Content);
-
- target.DataContext = "Foo";
-
- Assert.Null(target.Content);
-
- DelayedBinding.ApplyBindings(target);
-
- Assert.Equal("Foo", target.Content);
- }
- }
-
[Fact]
public void Double_Xaml_Binding_Is_Operational()
{
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs
index dbb34a7eba..44697f5937 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/EventTests.cs
@@ -5,7 +5,6 @@ using System;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
-using Portable.Xaml;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
@@ -35,19 +34,6 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
XamlTestHelpers.AssertThrowsXamlException(() => loader.Load(xaml, rootInstance: target));
}
- [Fact]
- public void Exception_Is_Not_Thrown_If_Event_Not_Found_In_Design_Mode()
- {
- // Runtime compiler should properly understand x:Class
- if (!AvaloniaXamlLoader.UseLegacyXamlLoader)
- return;
- var xaml = @"";
- var loader = new AvaloniaXamlLoader { IsDesignMode = true };
- var target = new MyButton();
-
- loader.Load(xaml, rootInstance: target);
- }
-
private void RaiseClick(MyButton target)
{
target.RaiseEvent(new KeyEventArgs
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
index a84ce74a88..8dd1d24dd6 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/StyleTests.cs
@@ -1,13 +1,13 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
+using System.Xml;
using Avalonia.Controls;
using Avalonia.Markup.Data;
using Avalonia.Markup.Xaml.Styling;
using Avalonia.Media;
using Avalonia.Styling;
using Avalonia.UnitTests;
-using Portable.Xaml;
using Xunit;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
@@ -191,7 +191,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
";
var loader = new AvaloniaXamlLoader();
- var ex = Assert.Throws(() => loader.Load(xaml));
+ var ex = Assert.Throws(() => loader.Load(xaml));
Assert.Equal(
"Property 'Button.IsDefault' is not registered on 'Avalonia.Controls.TextBlock'.",
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs
index 5e346e5289..5398e76f63 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlIlTests.cs
@@ -207,6 +207,33 @@ namespace Avalonia.Markup.Xaml.UnitTests
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'/>", typeof(XamlIlTests).Assembly);
Assert.Equal(Design.GetDataContext(loaded), SomeStaticProperty);
}
+
+ [Fact]
+ public void Attached_Properties_From_Static_Types_Should_Work_In_Style_Setters_Bug_2561()
+ {
+ using (UnitTestApplication.Start(TestServices.StyledWindow))
+ {
+
+ var parsed = (Window)AvaloniaXamlLoader.Parse(@"
+
+
+
+
+
+
+
+");
+ var tb = ((TextBox)parsed.Content);
+ parsed.Show();
+ tb.ApplyTemplate();
+ Assert.Equal(100, XamlIlBugTestsStaticClassWithAttachedProperty.GetTestInt(tb));
+ }
+ }
}
public class XamlIlBugTestsEventHandlerCodeBehind : Window
@@ -272,4 +299,19 @@ namespace Avalonia.Markup.Xaml.UnitTests
{
}
+ public static class XamlIlBugTestsStaticClassWithAttachedProperty
+ {
+ public static readonly AvaloniaProperty TestIntProperty = AvaloniaProperty
+ .RegisterAttached("TestInt", typeof(XamlIlBugTestsStaticClassWithAttachedProperty));
+
+ public static void SetTestInt(Control control, int value)
+ {
+ control.SetValue(TestIntProperty, value);
+ }
+
+ public static int GetTestInt(Control control)
+ {
+ return (int)control.GetValue(TestIntProperty);
+ }
+ }
}
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlTestHelpers.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlTestHelpers.cs
index 1b09ddc186..c23f01db07 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlTestHelpers.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/XamlTestHelpers.cs
@@ -1,6 +1,5 @@
using System;
using System.Xml;
-using Portable.Xaml;
namespace Avalonia.Markup.Xaml.UnitTests.Xaml
{
@@ -14,7 +13,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
}
catch (Exception e)
{
- if(e is XamlObjectWriterException || e is XmlException)
+ if(e is XmlException)
return;
}
throw new Exception("Expected to throw xaml exception");