diff --git a/packages.cake b/packages.cake
index bcb135f6ad..7e7e722c82 100644
--- a/packages.cake
+++ b/packages.cake
@@ -120,6 +120,7 @@ public class Packages
var SharpDXDirect3D11Version = packageVersions["SharpDX.Direct3D11"].FirstOrDefault().Item1;
var SharpDXDirect3D9Version = packageVersions["SharpDX.Direct3D9"].FirstOrDefault().Item1;
var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1;
+ var SystemComponentModelAnnotationsVersion = packageVersions["System.ComponentModel.Annotations"].FirstOrDefault().Item1;
context.Information("Package: Serilog, version: {0}", SerilogVersion);
context.Information("Package: Sprache, version: {0}", SpracheVersion);
@@ -238,6 +239,7 @@ public class Packages
new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion },
new NuSpecDependency() { Id = "Avalonia.Remote.Protocol", Version = parameters.Version },
+ new NuSpecDependency() { Id = "System.ComponentModel.Annotations", Version = SystemComponentModelAnnotationsVersion },
//.NET Core
new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp2.0", Version = "4.3.0" },
new NuSpecDependency() { Id = "Microsoft.Extensions.DependencyModel", TargetFramework = "netcoreapp2.0", Version = "1.1.0" },
diff --git a/readme.md b/readme.md
index 2b26cbdd1a..4fe76a2faf 100644
--- a/readme.md
+++ b/readme.md
@@ -18,7 +18,7 @@ Avalonia is a WPF-inspired cross-platform XAML-based UI framework providing a fl
## Getting Started
-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!
+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!
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))
@@ -52,7 +52,7 @@ Please read the [contribution guidelines](http://avaloniaui.net/contributing/con
### Contributors
This project exists thanks to all the people who contribute. [[Contribute](http://avaloniaui.net/contributing/contributing)].
-
+
### Backers
diff --git a/samples/ControlCatalog/DecoratedWindow.xaml.cs b/samples/ControlCatalog/DecoratedWindow.xaml.cs
index d28281e476..749f83c1ab 100644
--- a/samples/ControlCatalog/DecoratedWindow.xaml.cs
+++ b/samples/ControlCatalog/DecoratedWindow.xaml.cs
@@ -20,7 +20,7 @@ namespace ControlCatalog
ctl.Cursor = new Cursor(cursor);
ctl.PointerPressed += delegate
{
- PlatformImpl.BeginResizeDrag(edge);
+ PlatformImpl?.BeginResizeDrag(edge);
};
}
@@ -29,7 +29,7 @@ namespace ControlCatalog
AvaloniaXamlLoader.Load(this);
this.FindControl("TitleBar").PointerPressed += delegate
{
- PlatformImpl.BeginMoveDrag();
+ PlatformImpl?.BeginMoveDrag();
};
SetupSide("Left", StandardCursorType.LeftSide, WindowEdge.West);
SetupSide("Right", StandardCursorType.RightSide, WindowEdge.East);
diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs
index 78f744cea0..041d91043a 100644
--- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs
+++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/PopupImpl.cs
@@ -110,7 +110,10 @@ namespace Avalonia.Android.Platform.SkiaPlatform
{
//Not supported
}
-
+ public void SetTopmost(bool value)
+ {
+ //Not supported
+ }
}
}
\ No newline at end of file
diff --git a/src/Avalonia.Controls/AutoCompleteBox.cs b/src/Avalonia.Controls/AutoCompleteBox.cs
index 351cbf5520..96fb9be8ac 100644
--- a/src/Avalonia.Controls/AutoCompleteBox.cs
+++ b/src/Avalonia.Controls/AutoCompleteBox.cs
@@ -2150,7 +2150,7 @@ namespace Avalonia.Controls
}
// Update the view
- if (e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace)
+ if ((e.Action == NotifyCollectionChangedAction.Remove || e.Action == NotifyCollectionChangedAction.Replace) && e.OldItems != null)
{
for (int index = 0; index < e.OldItems.Count; index++)
{
diff --git a/src/Avalonia.Controls/Calendar/Calendar.cs b/src/Avalonia.Controls/Calendar/Calendar.cs
index 59281c5ad0..029e4dadc8 100644
--- a/src/Avalonia.Controls/Calendar/Calendar.cs
+++ b/src/Avalonia.Controls/Calendar/Calendar.cs
@@ -769,7 +769,7 @@ namespace Avalonia.Controls
}
private static void UpdateDisplayDate(Calendar c, DateTime addedDate, DateTime removedDate)
{
- Debug.Assert(c != null, "c should not be null!");
+ Contract.Requires(c != null);
// If DisplayDate < DisplayDateStart, DisplayDate = DisplayDateStart
if (DateTime.Compare(addedDate, c.DisplayDateRangeStart) < 0)
@@ -1016,8 +1016,6 @@ namespace Avalonia.Controls
internal CalendarDayButton FindDayButtonFromDay(DateTime day)
{
- CalendarDayButton b;
- DateTime? d;
CalendarItem monthControl = MonthControl;
// REMOVE_RTM: should be updated if we support MultiCalendar
@@ -1028,14 +1026,16 @@ namespace Avalonia.Controls
{
for (int childIndex = ColumnsPerMonth; childIndex < count; childIndex++)
{
- b = monthControl.MonthView.Children[childIndex] as CalendarDayButton;
- d = b.DataContext as DateTime?;
-
- if (d.HasValue)
+ if (monthControl.MonthView.Children[childIndex] is CalendarDayButton b)
{
- if (DateTimeHelper.CompareDays(d.Value, day) == 0)
+ var d = b.DataContext as DateTime?;
+
+ if (d.HasValue)
{
- return b;
+ if (DateTimeHelper.CompareDays(d.Value, day) == 0)
+ {
+ return b;
+ }
}
}
}
@@ -1044,20 +1044,6 @@ namespace Avalonia.Controls
return null;
}
- private void Calendar_SizeChanged(object sender, EventArgs e)
- {
- Debug.Assert(sender is Calendar, "The sender should be a Calendar!");
-
- var size = Bounds.Size;
- RectangleGeometry rg = new RectangleGeometry();
- rg.Rect = new Rect(0, 0, size.Width, size.Height);
-
- if (Root != null)
- {
- Root.Clip = rg;
- }
- }
-
private void OnSelectedMonthChanged(DateTime? selectedMonth)
{
if (selectedMonth.HasValue)
@@ -1090,7 +1076,6 @@ namespace Avalonia.Controls
internal void ResetStates()
{
- CalendarDayButton d;
CalendarItem monthControl = MonthControl;
int count = RowsPerMonth * ColumnsPerMonth;
if (monthControl != null)
@@ -1099,7 +1084,7 @@ namespace Avalonia.Controls
{
for (int childIndex = ColumnsPerMonth; childIndex < count; childIndex++)
{
- d = monthControl.MonthView.Children[childIndex] as CalendarDayButton;
+ var d = (CalendarDayButton)monthControl.MonthView.Children[childIndex];
d.IgnoreMouseOverState();
}
}
@@ -1190,8 +1175,6 @@ namespace Avalonia.Controls
if (HoverEnd != null && HoverStart != null)
{
int startIndex, endIndex, i;
- CalendarDayButton b;
- DateTime? d;
CalendarItem monthControl = MonthControl;
// This assumes a contiguous set of dates:
@@ -1201,18 +1184,20 @@ namespace Avalonia.Controls
for (i = startIndex; i <= endIndex; i++)
{
- b = monthControl.MonthView.Children[i] as CalendarDayButton;
- b.IsSelected = true;
- d = b.DataContext as DateTime?;
-
- if (d.HasValue && DateTimeHelper.CompareDays(HoverEnd.Value, d.Value) == 0)
+ if (monthControl.MonthView.Children[i] is CalendarDayButton b)
{
- if (FocusButton != null)
+ b.IsSelected = true;
+ var d = b.DataContext as DateTime?;
+
+ if (d.HasValue && DateTimeHelper.CompareDays(HoverEnd.Value, d.Value) == 0)
{
- FocusButton.IsCurrent = false;
+ if (FocusButton != null)
+ {
+ FocusButton.IsCurrent = false;
+ }
+ b.IsCurrent = HasFocusInternal;
+ FocusButton = b;
}
- b.IsCurrent = HasFocusInternal;
- FocusButton = b;
}
}
}
@@ -1228,8 +1213,6 @@ namespace Avalonia.Controls
if (HoverEnd != null && HoverStart != null)
{
CalendarItem monthControl = MonthControl;
- CalendarDayButton b;
- DateTime? d;
if (HoverEndIndex != null && HoverStartIndex != null)
{
@@ -1240,15 +1223,17 @@ namespace Avalonia.Controls
{
for (i = startIndex; i <= endIndex; i++)
{
- b = monthControl.MonthView.Children[i] as CalendarDayButton;
- d = b.DataContext as DateTime?;
-
- if (d.HasValue)
+ if (monthControl.MonthView.Children[i] is CalendarDayButton b)
{
- if (!SelectedDates.Contains(d.Value))
+ var d = b.DataContext as DateTime?;
+
+ if (d.HasValue)
{
- b.IsSelected = false;
- }
+ if (!SelectedDates.Contains(d.Value))
+ {
+ b.IsSelected = false;
+ }
+ }
}
}
}
@@ -1257,7 +1242,7 @@ namespace Avalonia.Controls
// It is SingleRange
for (i = startIndex; i <= endIndex; i++)
{
- (monthControl.MonthView.Children[i] as CalendarDayButton).IsSelected = false;
+ ((CalendarDayButton)monthControl.MonthView.Children[i]).IsSelected = false;
}
}
}
@@ -1628,16 +1613,15 @@ namespace Avalonia.Controls
e.Handled = true;
}
}
- internal void Calendar_KeyDown(object sender, KeyEventArgs e)
- {
- Calendar c = sender as Calendar;
- Debug.Assert(c != null, "c should not be null!");
- if (!e.Handled && c.IsEnabled)
+ internal void Calendar_KeyDown(KeyEventArgs e)
+ {
+ if (!e.Handled && IsEnabled)
{
e.Handled = ProcessCalendarKey(e);
}
}
+
internal bool ProcessCalendarKey(KeyEventArgs e)
{
if (DisplayMode == CalendarMode.Month)
@@ -1976,7 +1960,7 @@ namespace Avalonia.Controls
}
}
}
- private void Calendar_KeyUp(object sender, KeyEventArgs e)
+ private void Calendar_KeyUp(KeyEventArgs e)
{
if (!e.Handled && (e.Key == Key.LeftShift || e.Key == Key.RightShift))
{
@@ -2083,6 +2067,9 @@ namespace Avalonia.Controls
DisplayDateProperty.Changed.AddClassHandler(x => x.OnDisplayDateChanged);
DisplayDateStartProperty.Changed.AddClassHandler(x => x.OnDisplayDateStartChanged);
DisplayDateEndProperty.Changed.AddClassHandler(x => x.OnDisplayDateEndChanged);
+ KeyDownEvent.AddClassHandler(x => x.Calendar_KeyDown);
+ KeyUpEvent.AddClassHandler(x => x.Calendar_KeyUp);
+
}
///
@@ -2122,10 +2109,6 @@ namespace Avalonia.Controls
month.Owner = this;
}
}
-
- LayoutUpdated += Calendar_SizeChanged;
- KeyDown += Calendar_KeyDown;
- KeyUp += Calendar_KeyUp;
}
}
diff --git a/src/Avalonia.Controls/Calendar/CalendarDateRange.cs b/src/Avalonia.Controls/Calendar/CalendarDateRange.cs
index 273cda8c5b..718cc7142b 100644
--- a/src/Avalonia.Controls/Calendar/CalendarDateRange.cs
+++ b/src/Avalonia.Controls/Calendar/CalendarDateRange.cs
@@ -66,7 +66,7 @@ namespace Avalonia.Controls
/// Inherited code: Requires comment 2.
internal bool ContainsAny(CalendarDateRange range)
{
- Debug.Assert(range != null, "range should not be null!");
+ Contract.Requires(range != null);
int start = DateTime.Compare(Start, range.Start);
diff --git a/src/Avalonia.Controls/Calendar/CalendarItem.cs b/src/Avalonia.Controls/Calendar/CalendarItem.cs
index 3432fa549d..b0cbd0be53 100644
--- a/src/Avalonia.Controls/Calendar/CalendarItem.cs
+++ b/src/Avalonia.Controls/Calendar/CalendarItem.cs
@@ -517,7 +517,7 @@ namespace Avalonia.Controls.Primitives
for (int childIndex = Calendar.ColumnsPerMonth; childIndex < count; childIndex++)
{
CalendarDayButton childButton = MonthView.Children[childIndex] as CalendarDayButton;
- Debug.Assert(childButton != null, "childButton should not be null!");
+ Contract.Requires(childButton != null);
childButton.Index = childIndex;
SetButtonState(childButton, dateToAdd);
@@ -554,7 +554,7 @@ namespace Avalonia.Controls.Primitives
for (int i = childIndex; i < count; i++)
{
childButton = MonthView.Children[i] as CalendarDayButton;
- Debug.Assert(childButton != null, "childButton should not be null!");
+ Contract.Requires(childButton != null);
// button needs a content to occupy the necessary space
// for the content presenter
childButton.Content = i.ToString(DateTimeHelper.GetCurrentDateFormat());
@@ -650,7 +650,7 @@ namespace Avalonia.Controls.Primitives
foreach (object child in YearView.Children)
{
CalendarButton childButton = child as CalendarButton;
- Debug.Assert(childButton != null, "childButton should not be null!");
+ Contract.Requires(childButton != null);
// There should be no time component. Time is 12:00 AM
DateTime day = new DateTime(_currentMonth.Year, count + 1, 1);
childButton.DataContext = day;
@@ -746,7 +746,7 @@ namespace Avalonia.Controls.Primitives
foreach (object child in YearView.Children)
{
CalendarButton childButton = child as CalendarButton;
- Debug.Assert(childButton != null, "childButton should not be null!");
+ Contract.Requires(childButton != null);
year = decade + count;
if (year <= DateTime.MaxValue.Year && year >= DateTime.MinValue.Year)
@@ -826,7 +826,7 @@ namespace Avalonia.Controls.Primitives
{
Owner.Focus();
}
- Button b = sender as Button;
+ Button b = (Button)sender;
DateTime d;
if (b.IsEnabled)
@@ -863,7 +863,7 @@ namespace Avalonia.Controls.Primitives
Owner.Focus();
}
- Button b = sender as Button;
+ Button b = (Button)sender;
if (b.IsEnabled)
{
Owner.OnPreviousClick();
@@ -878,7 +878,7 @@ namespace Avalonia.Controls.Primitives
{
Owner.Focus();
}
- Button b = sender as Button;
+ Button b = (Button)sender;
if (b.IsEnabled)
{
@@ -891,8 +891,7 @@ namespace Avalonia.Controls.Primitives
{
if (Owner != null)
{
- CalendarDayButton b = sender as CalendarDayButton;
- if (_isMouseLeftButtonDown && b != null && b.IsEnabled && !b.IsBlackout)
+ if (_isMouseLeftButtonDown && sender is CalendarDayButton b && b.IsEnabled && !b.IsBlackout)
{
// Update the states of all buttons to be selected starting
// from HoverStart to b
@@ -918,7 +917,7 @@ namespace Avalonia.Controls.Primitives
Debug.Assert(b.DataContext != null, "The DataContext should not be null!");
Owner.UnHighlightDays();
Owner.HoverEndIndex = b.Index;
- Owner.HoverEnd = (DateTime)b.DataContext;
+ Owner.HoverEnd = (DateTime?)b.DataContext;
// Update the States of the buttons
Owner.HighlightDays();
return;
@@ -931,7 +930,7 @@ namespace Avalonia.Controls.Primitives
{
if (_isMouseLeftButtonDown)
{
- CalendarDayButton b = sender as CalendarDayButton;
+ CalendarDayButton b = (CalendarDayButton)sender;
// The button is in Pressed state. Change the state to normal.
if (e.Device.Captured == b)
e.Device.Capture(null);
@@ -973,7 +972,7 @@ namespace Avalonia.Controls.Primitives
if (b.IsEnabled && !b.IsBlackout)
{
DateTime selectedDate = (DateTime)b.DataContext;
- Debug.Assert(selectedDate != null, "selectedDate should not be null!");
+ Contract.Requires(selectedDate != null);
_isMouseLeftButtonDown = true;
// null check is added for unit tests
if (e != null)
@@ -1149,7 +1148,7 @@ namespace Avalonia.Controls.Primitives
if (_isControlPressed && Owner.SelectionMode == CalendarSelectionMode.MultipleRange)
{
CalendarDayButton b = sender as CalendarDayButton;
- Debug.Assert(b != null, "The sender should be a non-null CalendarDayButton!");
+ Contract.Requires(b != null);
if (b.IsSelected)
{
@@ -1169,7 +1168,7 @@ namespace Avalonia.Controls.Primitives
private void Month_CalendarButtonMouseDown(object sender, PointerPressedEventArgs e)
{
CalendarButton b = sender as CalendarButton;
- Debug.Assert(b != null, "The sender should be a non-null CalendarDayButton!");
+ Contract.Requires(b != null);
_isMouseLeftButtonDownYearView = true;
@@ -1208,7 +1207,7 @@ namespace Avalonia.Controls.Primitives
if (_isMouseLeftButtonDownYearView)
{
CalendarButton b = sender as CalendarButton;
- Debug.Assert(b != null, "The sender should be a non-null CalendarDayButton!");
+ Contract.Requires(b != null);
UpdateYearViewSelection(b);
}
}
@@ -1217,7 +1216,7 @@ namespace Avalonia.Controls.Primitives
{
if (_isMouseLeftButtonDownYearView)
{
- CalendarButton b = sender as CalendarButton;
+ CalendarButton b = (CalendarButton)sender;
// The button is in Pressed state. Change the state to normal.
if (e.Device.Captured == b)
e.Device.Capture(null);
diff --git a/src/Avalonia.Controls/Calendar/DatePicker.cs b/src/Avalonia.Controls/Calendar/DatePicker.cs
index 418ef50b2c..08608ad359 100644
--- a/src/Avalonia.Controls/Calendar/DatePicker.cs
+++ b/src/Avalonia.Controls/Calendar/DatePicker.cs
@@ -842,7 +842,7 @@ namespace Avalonia.Controls
private void Calendar_KeyDown(object sender, KeyEventArgs e)
{
Calendar c = sender as Calendar;
- Debug.Assert(c != null, "The Calendar should not be null!");
+ Contract.Requires(c != null);
if (!e.Handled && (e.Key == Key.Enter || e.Key == Key.Space || e.Key == Key.Escape) && c.DisplayMode == CalendarMode.Month)
{
diff --git a/src/Avalonia.Controls/Design.cs b/src/Avalonia.Controls/Design.cs
index ce52891749..894240a09f 100644
--- a/src/Avalonia.Controls/Design.cs
+++ b/src/Avalonia.Controls/Design.cs
@@ -1,5 +1,6 @@
using System.Runtime.CompilerServices;
+using Avalonia.Styling;
namespace Avalonia.Controls
{
@@ -45,23 +46,18 @@ namespace Avalonia.Controls
{
return control.GetValue(DataContextProperty);
}
-
- static readonly ConditionalWeakTable