diff --git a/Avalonia.Desktop.slnf b/Avalonia.Desktop.slnf
index 3acd4bf9f2..741570061b 100644
--- a/Avalonia.Desktop.slnf
+++ b/Avalonia.Desktop.slnf
@@ -45,6 +45,7 @@
"tests\\Avalonia.Base.UnitTests\\Avalonia.Base.UnitTests.csproj",
"tests\\Avalonia.Benchmarks\\Avalonia.Benchmarks.csproj",
"tests\\Avalonia.Controls.DataGrid.UnitTests\\Avalonia.Controls.DataGrid.UnitTests.csproj",
+ "tests\\Avalonia.Controls.ItemsRepeater.UnitTests\\Avalonia.Controls.ItemsRepeater.UnitTests.csproj",
"tests\\Avalonia.Controls.UnitTests\\Avalonia.Controls.UnitTests.csproj",
"tests\\Avalonia.DesignerSupport.TestApp\\Avalonia.DesignerSupport.TestApp.csproj",
"tests\\Avalonia.DesignerSupport.Tests\\Avalonia.DesignerSupport.Tests.csproj",
diff --git a/samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs b/samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs
index 11e5e32cf1..938c45a4e2 100644
--- a/samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs
+++ b/samples/ControlCatalog/Pages/CustomDrawingExampleControl.cs
@@ -59,10 +59,12 @@ namespace ControlCatalog.Pages
};
StreamGeometry sg = new StreamGeometry();
- var cntx = sg.Open();
- cntx.BeginFigure(new Point(-25.0d, -10.0d), false);
- cntx.ArcTo(new Point(25.0d, -10.0d), new Size(10.0d, 10.0d), 0.0d, false, SweepDirection.Clockwise);
- cntx.EndFigure(true);
+ using (var cntx = sg.Open())
+ {
+ cntx.BeginFigure(new Point(-25.0d, -10.0d), false);
+ cntx.ArcTo(new Point(25.0d, -10.0d), new Size(10.0d, 10.0d), 0.0d, false, SweepDirection.Clockwise);
+ cntx.EndFigure(true);
+ }
_smileGeometry = sg.Clone();
}
diff --git a/samples/IntegrationTestApp/MainWindow.axaml b/samples/IntegrationTestApp/MainWindow.axaml
index b116e4c789..4e5a8463df 100644
--- a/samples/IntegrationTestApp/MainWindow.axaml
+++ b/samples/IntegrationTestApp/MainWindow.axaml
@@ -70,6 +70,7 @@
Item 0
Item 1
+ Wrap Selection
diff --git a/samples/interop/WindowsInteropTest/Program.cs b/samples/interop/WindowsInteropTest/Program.cs
index fac06d74b0..c2d30c67bb 100644
--- a/samples/interop/WindowsInteropTest/Program.cs
+++ b/samples/interop/WindowsInteropTest/Program.cs
@@ -1,5 +1,4 @@
using System;
-using Avalonia.Controls;
using ControlCatalog;
using Avalonia;
@@ -15,7 +14,15 @@ namespace WindowsInteropTest
{
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
- AppBuilder.Configure().UseWin32().UseDirect2D1().SetupWithoutStarting();
+ AppBuilder.Configure()
+ .UseWin32()
+ .UseDirect2D1()
+ .With(new Win32PlatformOptions
+ {
+ UseWindowsUIComposition = false,
+ ShouldRenderOnUIThread = true // necessary for WPF
+ })
+ .SetupWithoutStarting();
System.Windows.Forms.Application.Run(new SelectorForm());
}
}
diff --git a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
index 1643ca3ee2..95f77f6df9 100644
--- a/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
+++ b/samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
@@ -2,7 +2,7 @@
WinExe
net461
-
+ x64
true
true
@@ -10,9 +10,6 @@
-
- {d0a739b9-3c68-4ba6-a328-41606954b6bd}
- ControlCatalog
-
+
diff --git a/src/Avalonia.Base/Rendering/DefaultRenderTimer.cs b/src/Avalonia.Base/Rendering/DefaultRenderTimer.cs
index d0d3dd9715..7b0fecf675 100644
--- a/src/Avalonia.Base/Rendering/DefaultRenderTimer.cs
+++ b/src/Avalonia.Base/Rendering/DefaultRenderTimer.cs
@@ -1,6 +1,4 @@
using System;
-using System.Diagnostics;
-using System.Threading.Tasks;
using Avalonia.Platform;
namespace Avalonia.Rendering
@@ -59,7 +57,8 @@ namespace Avalonia.Rendering
}
}
- public bool RunsInBackground => true;
+ ///
+ public virtual bool RunsInBackground => true;
///
/// Starts the timer.
diff --git a/src/Avalonia.Base/Rendering/IRenderLoop.cs b/src/Avalonia.Base/Rendering/IRenderLoop.cs
index e500ecdf8b..ebe683949d 100644
--- a/src/Avalonia.Base/Rendering/IRenderLoop.cs
+++ b/src/Avalonia.Base/Rendering/IRenderLoop.cs
@@ -27,7 +27,10 @@ namespace Avalonia.Rendering
///
/// The update task.
void Remove(IRenderLoopTask i);
-
+
+ ///
+ /// Indicates if the rendering is done on a non-UI thread.
+ ///
bool RunsInBackground { get; }
}
}
diff --git a/src/Avalonia.Base/Rendering/RenderLoop.cs b/src/Avalonia.Base/Rendering/RenderLoop.cs
index 1f58ca3827..185f44d29a 100644
--- a/src/Avalonia.Base/Rendering/RenderLoop.cs
+++ b/src/Avalonia.Base/Rendering/RenderLoop.cs
@@ -87,6 +87,7 @@ namespace Avalonia.Rendering
}
}
+ ///
public bool RunsInBackground => Timer.RunsInBackground;
private void TimerTick(TimeSpan time)
diff --git a/src/Avalonia.Base/Rendering/UiThreadRenderTimer.cs b/src/Avalonia.Base/Rendering/UiThreadRenderTimer.cs
index 1bbf804b5f..7f2eedc98c 100644
--- a/src/Avalonia.Base/Rendering/UiThreadRenderTimer.cs
+++ b/src/Avalonia.Base/Rendering/UiThreadRenderTimer.cs
@@ -8,13 +8,20 @@ namespace Avalonia.Rendering
///
/// Render timer that ticks on UI thread. Useful for debugging or bootstrapping on new platforms
///
-
public class UiThreadRenderTimer : DefaultRenderTimer
{
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The number of frames per second at which the loop should run.
public UiThreadRenderTimer(int framesPerSecond) : base(framesPerSecond)
{
}
+ ///
+ public override bool RunsInBackground => false;
+
+ ///
protected override IDisposable StartCore(Action tick)
{
bool cancelled = false;
diff --git a/src/Avalonia.Controls/Border.cs b/src/Avalonia.Controls/Border.cs
index 1bb574acd2..78ba23c1dd 100644
--- a/src/Avalonia.Controls/Border.cs
+++ b/src/Avalonia.Controls/Border.cs
@@ -225,7 +225,7 @@ namespace Avalonia.Controls
/// Renders the control.
///
/// The drawing context.
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
_borderRenderHelper.Render(context, Bounds.Size, LayoutThickness, CornerRadius, Background, BorderBrush,
BoxShadow, BorderDashOffset, BorderLineCap, BorderLineJoin, BorderDashArray);
diff --git a/src/Avalonia.Controls/ComboBox.cs b/src/Avalonia.Controls/ComboBox.cs
index b7a298bb16..17a6ad7a09 100644
--- a/src/Avalonia.Controls/ComboBox.cs
+++ b/src/Avalonia.Controls/ComboBox.cs
@@ -1,19 +1,19 @@
using System;
+using System.Diagnostics;
using System.Linq;
using Avalonia.Automation.Peers;
-using Avalonia.Reactive;
-using Avalonia.Controls.Generators;
-using Avalonia.Controls.Mixins;
-using Avalonia.Controls.Presenters;
+using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives;
+using Avalonia.Controls.Selection;
using Avalonia.Controls.Shapes;
using Avalonia.Controls.Templates;
+using Avalonia.Controls.Utils;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Layout;
using Avalonia.Media;
+using Avalonia.Reactive;
using Avalonia.VisualTree;
-using Avalonia.Controls.Metadata;
namespace Avalonia.Controls
{
@@ -219,7 +219,7 @@ namespace Avalonia.Controls
}
else if (e.Key == Key.Up)
{
- SelectPrev();
+ SelectPrevious();
e.Handled = true;
}
}
@@ -250,7 +250,7 @@ namespace Avalonia.Controls
if (e.Delta.Y < 0)
SelectNext();
else
- SelectPrev();
+ SelectPrevious();
e.Handled = true;
}
@@ -478,19 +478,40 @@ namespace Avalonia.Controls
}
}
- private void SelectNext()
- {
- if (ItemCount >= 1)
- {
- MoveSelection(NavigationDirection.Next, WrapSelection);
- }
- }
+ private void SelectNext() => MoveSelection(SelectedIndex, 1, WrapSelection);
+ private void SelectPrevious() => MoveSelection(SelectedIndex, -1, WrapSelection);
- private void SelectPrev()
+ private void MoveSelection(int startIndex, int step, bool wrap)
{
- if (ItemCount >= 1)
+ static bool IsSelectable(object? o) => (o as AvaloniaObject)?.GetValue(IsEnabledProperty) ?? true;
+
+ var count = ItemCount;
+
+ for (int i = startIndex + step; i != startIndex; i += step)
{
- MoveSelection(NavigationDirection.Previous, WrapSelection);
+ if (i < 0 || i >= count)
+ {
+ if (wrap)
+ {
+ if (i < 0)
+ i += count;
+ else if (i >= count)
+ i %= count;
+ }
+ else
+ {
+ return;
+ }
+ }
+
+ var item = ItemsView[i];
+ var container = ContainerFromIndex(i);
+
+ if (IsSelectable(item) && IsSelectable(container))
+ {
+ SelectedIndex = i;
+ break;
+ }
}
}
}
diff --git a/src/Avalonia.Controls/ExperimentalAcrylicBorder.cs b/src/Avalonia.Controls/ExperimentalAcrylicBorder.cs
index e4487d29fa..e1f840672d 100644
--- a/src/Avalonia.Controls/ExperimentalAcrylicBorder.cs
+++ b/src/Avalonia.Controls/ExperimentalAcrylicBorder.cs
@@ -80,7 +80,7 @@ namespace Avalonia.Controls
_subscription?.Dispose();
}
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
if (context.PlatformImpl is IDrawingContextWithAcrylicLikeSupport idc)
{
diff --git a/src/Avalonia.Controls/Grid.cs b/src/Avalonia.Controls/Grid.cs
index 2501440ff2..ff9fb4e31d 100644
--- a/src/Avalonia.Controls/Grid.cs
+++ b/src/Avalonia.Controls/Grid.cs
@@ -3256,7 +3256,7 @@ namespace Avalonia.Controls
///
/// UpdateRenderBounds.
///
- public override void Render(DrawingContext drawingContext)
+ public sealed override void Render(DrawingContext drawingContext)
{
var grid = this.GetVisualParent();
diff --git a/src/Avalonia.Controls/Image.cs b/src/Avalonia.Controls/Image.cs
index 2cf0fc3ec4..3e76835e92 100644
--- a/src/Avalonia.Controls/Image.cs
+++ b/src/Avalonia.Controls/Image.cs
@@ -73,7 +73,7 @@ namespace Avalonia.Controls
/// Renders the control.
///
/// The drawing context.
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
var source = Source;
diff --git a/src/Avalonia.Controls/Panel.cs b/src/Avalonia.Controls/Panel.cs
index 007d18c813..a7dc035459 100644
--- a/src/Avalonia.Controls/Panel.cs
+++ b/src/Avalonia.Controls/Panel.cs
@@ -68,7 +68,7 @@ namespace Avalonia.Controls
/// Renders the visual to a .
///
/// The drawing context.
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
var background = Background;
if (background != null)
diff --git a/src/Avalonia.Controls/Presenters/ContentPresenter.cs b/src/Avalonia.Controls/Presenters/ContentPresenter.cs
index 584dfea97f..be61bb18a1 100644
--- a/src/Avalonia.Controls/Presenters/ContentPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/ContentPresenter.cs
@@ -534,7 +534,7 @@ namespace Avalonia.Controls.Presenters
}
///
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
_borderRenderer.Render(context, Bounds.Size, LayoutThickness, CornerRadius, Background, BorderBrush,
BoxShadow);
diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs
index f599511392..3481b1ecf3 100644
--- a/src/Avalonia.Controls/Presenters/TextPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs
@@ -388,7 +388,7 @@ namespace Avalonia.Controls.Presenters
TextLayout.Draw(context, new Point(left, top));
}
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
var selectionStart = SelectionStart;
var selectionEnd = SelectionEnd;
diff --git a/src/Avalonia.Controls/Primitives/AccessText.cs b/src/Avalonia.Controls/Primitives/AccessText.cs
index 49e76d0728..ed3412bb45 100644
--- a/src/Avalonia.Controls/Primitives/AccessText.cs
+++ b/src/Avalonia.Controls/Primitives/AccessText.cs
@@ -60,10 +60,9 @@ namespace Avalonia.Controls.Primitives
/// Renders the to a drawing context.
///
/// The drawing context.
- public override void Render(DrawingContext context)
+ protected internal override void RenderCore(DrawingContext context)
{
- base.Render(context);
-
+ base.RenderCore(context);
int underscore = Text?.IndexOf('_') ?? -1;
if (underscore != -1 && ShowAccessKey)
diff --git a/src/Avalonia.Controls/Remote/RemoteWidget.cs b/src/Avalonia.Controls/Remote/RemoteWidget.cs
index 5cefb0d89f..b9854ab837 100644
--- a/src/Avalonia.Controls/Remote/RemoteWidget.cs
+++ b/src/Avalonia.Controls/Remote/RemoteWidget.cs
@@ -69,7 +69,7 @@ namespace Avalonia.Controls.Remote
base.ArrangeCore(finalRect);
}
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
if (_lastFrame != null && _lastFrame.Width != 0 && _lastFrame.Height != 0)
{
diff --git a/src/Avalonia.Controls/ScrollViewer.cs b/src/Avalonia.Controls/ScrollViewer.cs
index ab114da933..af874bd380 100644
--- a/src/Avalonia.Controls/ScrollViewer.cs
+++ b/src/Avalonia.Controls/ScrollViewer.cs
@@ -775,6 +775,22 @@ namespace Avalonia.Controls
control.SetValue(VerticalScrollBarVisibilityProperty, value);
}
+ ///
+ /// Gets whether scroll gestures should include inertia in their behavior and value.
+ ///
+ public static bool GetIsScrollInertiaEnabled(Control control)
+ {
+ return control.GetValue(IsScrollInertiaEnabledProperty);
+ }
+
+ ///
+ /// Sets whether scroll gestures should include inertia in their behavior and value.
+ ///
+ public static void SetIsScrollInertiaEnabled(Control control, bool value)
+ {
+ control.SetValue(IsScrollInertiaEnabledProperty, value);
+ }
+
///
public void RegisterAnchorCandidate(Control element)
{
diff --git a/src/Avalonia.Controls/Shapes/Shape.cs b/src/Avalonia.Controls/Shapes/Shape.cs
index c8bf95b3f7..461dc1c947 100644
--- a/src/Avalonia.Controls/Shapes/Shape.cs
+++ b/src/Avalonia.Controls/Shapes/Shape.cs
@@ -193,7 +193,7 @@ namespace Avalonia.Controls.Shapes
set { SetValue(StrokeJoinProperty, value); }
}
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
{
var geometry = RenderedGeometry;
diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs
index ec31470126..df98d1073e 100644
--- a/src/Avalonia.Controls/TextBlock.cs
+++ b/src/Avalonia.Controls/TextBlock.cs
@@ -549,7 +549,13 @@ namespace Avalonia.Controls
/// Renders the to a drawing context.
///
/// The drawing context.
- public override void Render(DrawingContext context)
+ public sealed override void Render(DrawingContext context)
+ {
+ RenderCore(context);
+ }
+
+ // Workaround to seal Render method, we need to make so because AccessText was overriding Render method which is sealed now.
+ internal protected virtual void RenderCore(DrawingContext context)
{
var background = Background;
diff --git a/src/Avalonia.Controls/TickBar.cs b/src/Avalonia.Controls/TickBar.cs
index 4d902d3d5f..63fe9c9384 100644
--- a/src/Avalonia.Controls/TickBar.cs
+++ b/src/Avalonia.Controls/TickBar.cs
@@ -213,7 +213,7 @@ namespace Avalonia.Controls
///
/// Brush that use to fill ticks is specified by Fill property.
///
- public override void Render(DrawingContext dc)
+ public sealed override void Render(DrawingContext dc)
{
var size = new Size(Bounds.Width, Bounds.Height);
var range = Maximum - Minimum;
diff --git a/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml b/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml
index 4b9fb76b8a..e2273cd487 100644
--- a/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml
+++ b/src/Avalonia.Themes.Fluent/Controls/ListBox.xaml
@@ -19,6 +19,7 @@
+
@@ -34,6 +35,7 @@
HorizontalScrollBarVisibility="{TemplateBinding (ScrollViewer.HorizontalScrollBarVisibility)}"
VerticalScrollBarVisibility="{TemplateBinding (ScrollViewer.VerticalScrollBarVisibility)}"
IsScrollChainingEnabled="{TemplateBinding (ScrollViewer.IsScrollChainingEnabled)}"
+ IsScrollInertiaEnabled="{TemplateBinding (ScrollViewer.IsScrollInertiaEnabled)}"
AllowAutoHide="{TemplateBinding (ScrollViewer.AllowAutoHide)}">
ClientSize;
}
@@ -223,7 +216,7 @@ namespace Avalonia.Win32.Interop.Wpf
(Key)e.Key,
GetModifiers(null)));
- protected override void OnTextInput(TextCompositionEventArgs e)
+ protected override void OnTextInput(TextCompositionEventArgs e)
=> _ttl.Input?.Invoke(new RawTextInputEventArgs(_keyboard, (uint) e.Timestamp, _inputRoot, e.Text));
void ITopLevelImpl.SetCursor(ICursorImpl cursor)
diff --git a/src/Windows/Avalonia.Win32/TrayIconImpl.cs b/src/Windows/Avalonia.Win32/TrayIconImpl.cs
index ab70d77a09..fe920ff1a1 100644
--- a/src/Windows/Avalonia.Win32/TrayIconImpl.cs
+++ b/src/Windows/Avalonia.Win32/TrayIconImpl.cs
@@ -81,19 +81,18 @@ namespace Avalonia.Win32
private void UpdateIcon(bool remove = false)
{
- var iconData = new NOTIFYICONDATA()
+ var iconData = new NOTIFYICONDATA
{
hWnd = Win32Platform.Instance.Handle,
- uID = _uniqueId,
- uFlags = NIF.TIP | NIF.MESSAGE,
- uCallbackMessage = (int)CustomWindowsMessage.WM_TRAYMOUSE,
- hIcon = _icon?.HIcon ?? s_emptyIcon,
- szTip = _tooltipText ?? ""
+ uID = _uniqueId
};
if (!remove)
{
- iconData.uFlags |= NIF.ICON;
+ iconData.uFlags = NIF.TIP | NIF.MESSAGE | NIF.ICON;
+ iconData.uCallbackMessage = (int)CustomWindowsMessage.WM_TRAYMOUSE;
+ iconData.hIcon = _icon?.HIcon ?? s_emptyIcon;
+ iconData.szTip = _tooltipText ?? "";
if (!_iconAdded)
{
@@ -107,6 +106,7 @@ namespace Avalonia.Win32
}
else
{
+ iconData.uFlags = 0;
Shell_NotifyIcon(NIM.DELETE, iconData);
_iconAdded = false;
}
diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs
index f16a1ca8cf..c34be9008a 100644
--- a/src/Windows/Avalonia.Win32/Win32Platform.cs
+++ b/src/Windows/Avalonia.Win32/Win32Platform.cs
@@ -6,12 +6,10 @@ using System.IO;
using Avalonia.Reactive;
using System.Runtime.InteropServices;
using System.Threading;
-using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Controls.Platform;
using Avalonia.Input;
using Avalonia.Input.Platform;
-using Avalonia.Media;
using Avalonia.OpenGL;
using Avalonia.Platform;
using Avalonia.Rendering;
@@ -20,7 +18,6 @@ using Avalonia.Threading;
using Avalonia.Utilities;
using Avalonia.Win32.Input;
using Avalonia.Win32.Interop;
-using Avalonia.Win32.WinRT;
using static Avalonia.Win32.Interop.UnmanagedMethods;
namespace Avalonia
@@ -68,6 +65,7 @@ namespace Avalonia
///
/// Render Avalonia to a Texture inside the Windows.UI.Composition tree.
+ /// This setting is true by default.
///
///
/// Supported on Windows 10 build 16299 and above. Ignored on other versions.
@@ -88,9 +86,19 @@ namespace Avalonia
/// This is only recommended if low input latency is desirable, and there is no need for the transparency
/// and stylings / blurrings offered by
/// This is mutually exclusive with
- /// which if active will override this setting.
+ /// which if active will override this setting.
+ /// This setting is false by default.
///
- public bool UseLowLatencyDxgiSwapChain { get; set; } = false;
+ public bool UseLowLatencyDxgiSwapChain { get; set; }
+
+ ///
+ /// Render directly on the UI thread instead of using a dedicated render thread.
+ /// Only applicable if both and
+ /// are false.
+ /// This setting is only recommended for interop with systems that must render on the UI thread, such as WPF.
+ /// This setting is false by default.
+ ///
+ public bool ShouldRenderOnUIThread { get; set; }
///
/// Provides a way to use a custom-implemented graphics context such as a custom ISkiaGpu
@@ -128,7 +136,7 @@ namespace Avalonia.Win32
internal static bool UseOverlayPopups => Options.OverlayPopups;
public static Win32PlatformOptions Options { get; private set; }
-
+
internal static Compositor Compositor { get; private set; }
public static void Initialize()
@@ -139,6 +147,8 @@ namespace Avalonia.Win32
public static void Initialize(Win32PlatformOptions options)
{
Options = options;
+ var renderTimer = options.ShouldRenderOnUIThread ? new UiThreadRenderTimer(60) : new DefaultRenderTimer(60);
+
AvaloniaLocator.CurrentMutable
.Bind().ToSingleton()
.Bind().ToConstant(CursorFactory.Instance)
@@ -146,7 +156,7 @@ namespace Avalonia.Win32
.Bind().ToSingleton()
.Bind().ToConstant(s_instance)
.Bind().ToConstant(new RenderLoop())
- .Bind().ToConstant(new DefaultRenderTimer(60))
+ .Bind().ToConstant(renderTimer)
.Bind().ToConstant(s_instance)
.Bind().ToConstant(new PlatformHotkeyConfiguration(KeyModifiers.Control)
{
diff --git a/tests/Avalonia.IntegrationTests.Appium/ComboBoxTests.cs b/tests/Avalonia.IntegrationTests.Appium/ComboBoxTests.cs
index abdb4e2dd8..8df7873582 100644
--- a/tests/Avalonia.IntegrationTests.Appium/ComboBoxTests.cs
+++ b/tests/Avalonia.IntegrationTests.Appium/ComboBoxTests.cs
@@ -47,7 +47,64 @@ namespace Avalonia.IntegrationTests.Appium
}
[PlatformFact(TestPlatforms.Windows)]
- public void Can_Change_Selection_With_Keyboard()
+ public void Can_Change_Selection_With_Keyboard_When_Closed()
+ {
+ var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");
+ var wrap = _session.FindElementByAccessibilityId("ComboBoxWrapSelection");
+
+ if (wrap.GetIsChecked() != false)
+ wrap.Click();
+
+ _session.FindElementByAccessibilityId("ComboBoxSelectionClear").Click();
+
+ comboBox.SendKeys(Keys.ArrowDown);
+ Assert.Equal("Item 0", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowDown);
+ Assert.Equal("Item 1", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowDown);
+ Assert.Equal("Item 1", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowUp);
+ Assert.Equal("Item 0", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowUp);
+ Assert.Equal("Item 0", comboBox.GetComboBoxValue());
+ }
+
+ [PlatformFact(TestPlatforms.Windows)]
+ public void Can_Change_Wrapping_Selection_With_Keyboard_When_Closed()
+ {
+ var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");
+ var wrap = _session.FindElementByAccessibilityId("ComboBoxWrapSelection");
+
+ if (wrap.GetIsChecked() != true)
+ wrap.Click();
+
+ _session.FindElementByAccessibilityId("ComboBoxSelectionClear").Click();
+
+ comboBox.SendKeys(Keys.ArrowDown);
+ Assert.Equal("Item 0", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowDown);
+ Assert.Equal("Item 1", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowDown);
+ Assert.Equal("Item 0", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowDown);
+ Assert.Equal("Item 1", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowUp);
+ Assert.Equal("Item 0", comboBox.GetComboBoxValue());
+
+ comboBox.SendKeys(Keys.ArrowUp);
+ Assert.Equal("Item 1", comboBox.GetComboBoxValue());
+ }
+
+ [PlatformFact(TestPlatforms.Windows)]
+ public void Can_Change_Selection_When_Open_With_Keyboard()
{
var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");
@@ -64,7 +121,7 @@ namespace Avalonia.IntegrationTests.Appium
}
[PlatformFact(TestPlatforms.Windows)]
- public void Can_Change_Selection_With_Keyboard_From_Unselected()
+ public void Can_Change_Selection_When_Open_With_Keyboard_From_Unselected()
{
var comboBox = _session.FindElementByAccessibilityId("BasicComboBox");