diff --git a/.editorconfig b/.editorconfig
index 64fe33bbae..b7a03207a4 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -1,11 +1,159 @@
-; This file is for unifying the coding style for different editors and IDEs.
-; More information at http://EditorConfig.org
+# editorconfig.org
+# top-most EditorConfig file
root = true
+# Default settings:
+# A newline ending every file
+# Use 4 spaces as indentation
[*]
-end_of_line = CRLF
+insert_final_newline = true
+indent_style = space
+indent_size = 4
+# C# files
[*.cs]
-indent_style = space
+# New line preferences
+csharp_new_line_before_open_brace = all
+csharp_new_line_before_else = true
+csharp_new_line_before_catch = true
+csharp_new_line_before_finally = true
+csharp_new_line_before_members_in_object_initializers = true
+csharp_new_line_before_members_in_anonymous_types = true
+csharp_new_line_between_query_expression_clauses = true
+
+# Indentation preferences
+csharp_indent_block_contents = true
+csharp_indent_braces = false
+csharp_indent_case_contents = true
+csharp_indent_switch_labels = true
+csharp_indent_labels = one_less_than_current
+
+# avoid this. unless absolutely necessary
+dotnet_style_qualification_for_field = false:suggestion
+dotnet_style_qualification_for_property = false:suggestion
+dotnet_style_qualification_for_method = false:suggestion
+dotnet_style_qualification_for_event = false:suggestion
+
+# prefer var
+csharp_style_var_for_built_in_types = true
+csharp_style_var_when_type_is_apparent = true
+csharp_style_var_elsewhere = true:suggestion
+
+# use language keywords instead of BCL types
+dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
+dotnet_style_predefined_type_for_member_access = true:suggestion
+
+# name all constant fields using PascalCase
+dotnet_naming_rule.constant_fields_should_be_pascal_case.severity = suggestion
+dotnet_naming_rule.constant_fields_should_be_pascal_case.symbols = constant_fields
+dotnet_naming_rule.constant_fields_should_be_pascal_case.style = pascal_case_style
+
+dotnet_naming_symbols.constant_fields.applicable_kinds = field
+dotnet_naming_symbols.constant_fields.required_modifiers = const
+
+dotnet_naming_style.pascal_case_style.capitalization = pascal_case
+
+# static fields should have s_ prefix
+dotnet_naming_rule.static_fields_should_have_prefix.severity = suggestion
+dotnet_naming_rule.static_fields_should_have_prefix.symbols = static_fields
+dotnet_naming_rule.static_fields_should_have_prefix.style = static_prefix_style
+
+dotnet_naming_symbols.static_fields.applicable_kinds = field
+dotnet_naming_symbols.static_fields.required_modifiers = static
+
+dotnet_naming_style.static_prefix_style.required_prefix = s_
+dotnet_naming_style.static_prefix_style.capitalization = camel_case
+
+# internal and private fields should be _camelCase
+dotnet_naming_rule.camel_case_for_private_internal_fields.severity = suggestion
+dotnet_naming_rule.camel_case_for_private_internal_fields.symbols = private_internal_fields
+dotnet_naming_rule.camel_case_for_private_internal_fields.style = camel_case_underscore_style
+
+dotnet_naming_symbols.private_internal_fields.applicable_kinds = field
+dotnet_naming_symbols.private_internal_fields.applicable_accessibilities = private, internal
+
+dotnet_naming_style.camel_case_underscore_style.required_prefix = _
+dotnet_naming_style.camel_case_underscore_style.capitalization = camel_case
+
+# use accessibility modifiers
+dotnet_style_require_accessibility_modifiers = for_non_interface_members:suggestion
+
+# Code style defaults
+dotnet_sort_system_directives_first = true
+csharp_preserve_single_line_blocks = true
+csharp_preserve_single_line_statements = false
+
+# Expression-level preferences
+dotnet_style_object_initializer = true:suggestion
+dotnet_style_collection_initializer = true:suggestion
+dotnet_style_explicit_tuple_names = true:suggestion
+dotnet_style_coalesce_expression = true:suggestion
+dotnet_style_null_propagation = true:suggestion
+
+# Expression-bodied members
+csharp_style_expression_bodied_methods = false:none
+csharp_style_expression_bodied_constructors = false:none
+csharp_style_expression_bodied_operators = false:none
+csharp_style_expression_bodied_properties = true:none
+csharp_style_expression_bodied_indexers = true:none
+csharp_style_expression_bodied_accessors = true:none
+
+# Pattern matching
+csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
+csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
+csharp_style_inlined_variable_declaration = true:suggestion
+
+# Null checking preferences
+csharp_style_throw_expression = true:suggestion
+csharp_style_conditional_delegate_call = true:suggestion
+
+# Space preferences
+csharp_space_after_cast = false
+csharp_space_after_colon_in_inheritance_clause = true
+csharp_space_after_comma = true
+csharp_space_after_dot = false
+csharp_space_after_keywords_in_control_flow_statements = true
+csharp_space_after_semicolon_in_for_statement = true
+csharp_space_around_binary_operators = before_and_after
+csharp_space_around_declaration_statements = do_not_ignore
+csharp_space_before_colon_in_inheritance_clause = true
+csharp_space_before_comma = false
+csharp_space_before_dot = false
+csharp_space_before_open_square_brackets = false
+csharp_space_before_semicolon_in_for_statement = false
+csharp_space_between_empty_square_brackets = false
+csharp_space_between_method_call_empty_parameter_list_parentheses = false
+csharp_space_between_method_call_name_and_opening_parenthesis = false
+csharp_space_between_method_call_parameter_list_parentheses = false
+csharp_space_between_method_declaration_empty_parameter_list_parentheses = false
+csharp_space_between_method_declaration_name_and_open_parenthesis = false
+csharp_space_between_method_declaration_parameter_list_parentheses = false
+csharp_space_between_parentheses = false
+csharp_space_between_square_brackets = false
+
+# Xaml files
+[*.xaml]
indent_size = 4
+
+# Xml project files
+[*.{csproj,vcxproj,vcxproj.filters,proj,nativeproj,locproj}]
+indent_size = 2
+
+# Xml build files
+[*.builds]
+indent_size = 2
+
+# Xml files
+[*.{xml,stylecop,resx,ruleset}]
+indent_size = 2
+
+# Xml config files
+[*.{props,targets,config,nuspec}]
+indent_size = 2
+
+# Shell scripts
+[*.sh]
+end_of_line = lf
+[*.{cmd, bat}]
+end_of_line = crlf
diff --git a/Avalonia.sln b/Avalonia.sln
index 75bca0bca8..d1c5026e58 100644
--- a/Avalonia.sln
+++ b/Avalonia.sln
@@ -58,6 +58,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9B9E
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Shared", "Shared", "{A689DEF5-D50F-4975-8B72-124C9EB54066}"
ProjectSection(SolutionItems) = preProject
+ .editorconfig = .editorconfig
src\Shared\SharedAssemblyInfo.cs = src\Shared\SharedAssemblyInfo.cs
EndProjectSection
EndProject
diff --git a/readme.md b/readme.md
index 4fe76a2faf..345ad7fe9b 100644
--- a/readme.md
+++ b/readme.md
@@ -20,6 +20,8 @@ Avalonia is a WPF-inspired cross-platform XAML-based UI framework providing a fl
Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio) contains project and control templates that will help you get started. After installing it, open "New Project" dialog in Visual Studio, choose "Avalonia" in "Visual C#" section, select "Avalonia .NET Core Application" and press OK (screenshot). Now you can write code and markup that will work on multiple platforms!
+For those without Visual Studio, starter guide for .NET Core CLI can be found [here](http://avaloniaui.net/docs/quickstart/create-new-project#net-core).
+
Avalonia is delivered via NuGet package manager. You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Avalonia/), [nightly](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed))
Use these commands in Package Manager console to install Avalonia manually:
diff --git a/src/Avalonia.Controls/Application.cs b/src/Avalonia.Controls/Application.cs
index de27aa94f8..499b65c5b7 100644
--- a/src/Avalonia.Controls/Application.cs
+++ b/src/Avalonia.Controls/Application.cs
@@ -332,7 +332,6 @@ namespace Avalonia
.Bind().ToConstant(InputManager)
.Bind().ToTransient()
.Bind().ToConstant(_styler)
- .Bind().ToSingleton()
.Bind().ToConstant(this)
.Bind().ToConstant(AvaloniaScheduler.Instance)
.Bind().ToConstant(DragDropDevice.Instance)
diff --git a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
index 179dccaf76..c177d43917 100644
--- a/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
+++ b/src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
@@ -28,7 +28,7 @@ namespace Avalonia.Controls.Embedding
{
EnsureInitialized();
ApplyTemplate();
- LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass(this);
}
private void EnsureInitialized()
diff --git a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
index 4db16c71a5..5becdc0f61 100644
--- a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
+++ b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevel.cs
@@ -22,7 +22,7 @@ namespace Avalonia.Controls.Embedding.Offscreen
{
EnsureInitialized();
ApplyTemplate();
- LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass(this);
}
private void EnsureInitialized()
diff --git a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
index c1489e7138..b98f26b87f 100644
--- a/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
+++ b/src/Avalonia.Controls/Presenters/ItemVirtualizerSimple.cs
@@ -518,7 +518,7 @@ namespace Avalonia.Controls.Presenters
}
var container = generator.ContainerFromIndex(index);
- var layoutManager = LayoutManager.Instance;
+ var layoutManager = (Owner.GetVisualRoot() as ILayoutRoot)?.LayoutManager;
// We need to do a layout here because it's possible that the container we moved to
// is only partially visible due to differing item sizes. If the container is only
diff --git a/src/Avalonia.Controls/TopLevel.cs b/src/Avalonia.Controls/TopLevel.cs
index 1af347ab4e..9fdc097c3f 100644
--- a/src/Avalonia.Controls/TopLevel.cs
+++ b/src/Avalonia.Controls/TopLevel.cs
@@ -54,6 +54,7 @@ namespace Avalonia.Controls
private readonly IApplicationLifecycle _applicationLifecycle;
private readonly IPlatformRenderInterface _renderInterface;
private Size _clientSize;
+ private ILayoutManager _layoutManager;
///
/// Initializes static members of the class.
@@ -147,6 +148,16 @@ namespace Avalonia.Controls
protected set { SetAndRaise(ClientSizeProperty, ref _clientSize, value); }
}
+ public ILayoutManager LayoutManager
+ {
+ get
+ {
+ if (_layoutManager == null)
+ _layoutManager = CreateLayoutManager();
+ return _layoutManager;
+ }
+ }
+
///
/// Gets the platform-specific window implementation.
///
@@ -235,6 +246,11 @@ namespace Avalonia.Controls
{
return PlatformImpl?.PointToScreen(p) ?? default(Point);
}
+
+ ///
+ /// Creates the layout manager for this .
+ ///
+ protected virtual ILayoutManager CreateLayoutManager() => new LayoutManager();
///
/// Handles a paint notification from .
@@ -267,7 +283,7 @@ namespace Avalonia.Controls
ClientSize = clientSize;
Width = clientSize.Width;
Height = clientSize.Height;
- LayoutManager.Instance.ExecuteLayoutPass();
+ LayoutManager.ExecuteLayoutPass();
Renderer?.Resized(clientSize);
}
diff --git a/src/Avalonia.Controls/Window.cs b/src/Avalonia.Controls/Window.cs
index bfb9973ee6..d1a023c42c 100644
--- a/src/Avalonia.Controls/Window.cs
+++ b/src/Avalonia.Controls/Window.cs
@@ -374,7 +374,7 @@ namespace Avalonia.Controls
EnsureInitialized();
IsVisible = true;
- LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass(this);
using (BeginAutoSizing())
{
@@ -416,7 +416,7 @@ namespace Avalonia.Controls
EnsureInitialized();
SetWindowStartupLocation();
IsVisible = true;
- LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass(this);
using (BeginAutoSizing())
{
diff --git a/src/Avalonia.Controls/WindowBase.cs b/src/Avalonia.Controls/WindowBase.cs
index 5d66bee2f8..c0b664ebc3 100644
--- a/src/Avalonia.Controls/WindowBase.cs
+++ b/src/Avalonia.Controls/WindowBase.cs
@@ -179,10 +179,9 @@ namespace Avalonia.Controls
if (!_hasExecutedInitialLayoutPass)
{
- LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+ LayoutManager.ExecuteInitialLayoutPass(this);
_hasExecutedInitialLayoutPass = true;
}
-
PlatformImpl?.Show();
Renderer?.Start();
}
@@ -262,7 +261,7 @@ namespace Avalonia.Controls
Height = clientSize.Height;
}
ClientSize = clientSize;
- LayoutManager.Instance.ExecuteLayoutPass();
+ LayoutManager.ExecuteLayoutPass();
Renderer?.Resized(clientSize);
}
diff --git a/src/Avalonia.Layout/ILayoutRoot.cs b/src/Avalonia.Layout/ILayoutRoot.cs
index 25a6331b38..700b6a8600 100644
--- a/src/Avalonia.Layout/ILayoutRoot.cs
+++ b/src/Avalonia.Layout/ILayoutRoot.cs
@@ -22,5 +22,10 @@ namespace Avalonia.Layout
/// The scaling factor to use in layout.
///
double LayoutScaling { get; }
+
+ ///
+ /// Associated instance of layout manager
+ ///
+ ILayoutManager LayoutManager { get; }
}
}
diff --git a/src/Avalonia.Layout/LayoutManager.cs b/src/Avalonia.Layout/LayoutManager.cs
index b6b786a077..9cf8521008 100644
--- a/src/Avalonia.Layout/LayoutManager.cs
+++ b/src/Avalonia.Layout/LayoutManager.cs
@@ -19,11 +19,6 @@ namespace Avalonia.Layout
private bool _queued;
private bool _running;
- ///
- /// Gets the layout manager.
- ///
- public static ILayoutManager Instance => AvaloniaLocator.Current.GetService();
-
///
public void InvalidateMeasure(ILayoutable control)
{
@@ -170,7 +165,7 @@ namespace Avalonia.Layout
{
root.Measure(Size.Infinity);
}
- else
+ else if (control.PreviousMeasure.HasValue)
{
control.Measure(control.PreviousMeasure.Value);
}
diff --git a/src/Avalonia.Layout/Layoutable.cs b/src/Avalonia.Layout/Layoutable.cs
index 523c720e2f..7112e216ff 100644
--- a/src/Avalonia.Layout/Layoutable.cs
+++ b/src/Avalonia.Layout/Layoutable.cs
@@ -389,7 +389,7 @@ namespace Avalonia.Layout
if (((ILayoutable)this).IsAttachedToVisualTree)
{
- LayoutManager.Instance?.InvalidateMeasure(this);
+ (VisualRoot as ILayoutRoot)?.LayoutManager.InvalidateMeasure(this);
InvalidateVisual();
}
OnMeasureInvalidated();
@@ -406,12 +406,8 @@ namespace Avalonia.Layout
Logger.Verbose(LogArea.Layout, this, "Invalidated arrange");
IsArrangeValid = false;
-
- if (((ILayoutable)this).IsAttachedToVisualTree)
- {
- LayoutManager.Instance?.InvalidateArrange(this);
- InvalidateVisual();
- }
+ (VisualRoot as ILayoutRoot)?.LayoutManager?.InvalidateArrange(this);
+ InvalidateVisual();
}
}
diff --git a/src/Avalonia.Themes.Default/MenuItem.xaml b/src/Avalonia.Themes.Default/MenuItem.xaml
index 53965db016..47b4528f88 100644
--- a/src/Avalonia.Themes.Default/MenuItem.xaml
+++ b/src/Avalonia.Themes.Default/MenuItem.xaml
@@ -122,11 +122,6 @@
-
-