diff --git a/native/Avalonia.Native/src/OSX/window.mm b/native/Avalonia.Native/src/OSX/window.mm
index e15f4cc311..7a6e7dc72f 100644
--- a/native/Avalonia.Native/src/OSX/window.mm
+++ b/native/Avalonia.Native/src/OSX/window.mm
@@ -641,6 +641,7 @@ private:
[Window setCanBecomeKeyAndMain];
[Window disableCursorRects];
[Window setTabbingMode:NSWindowTabbingModeDisallowed];
+ [Window setCollectionBehavior:NSWindowCollectionBehaviorFullScreenPrimary];
}
void HideOrShowTrafficLights ()
@@ -1091,14 +1092,7 @@ private:
{
_fullScreenActive = true;
- [Window setHasShadow:YES];
- [Window setTitleVisibility:NSWindowTitleVisible];
- [Window setTitlebarAppearsTransparent:NO];
[Window setTitle:_lastTitle];
-
- Window.styleMask = Window.styleMask | NSWindowStyleMaskTitled | NSWindowStyleMaskResizable;
- Window.styleMask = Window.styleMask & ~NSWindowStyleMaskFullSizeContentView;
-
[Window toggleFullScreen:nullptr];
}
diff --git a/src/Avalonia.Base/Collections/AvaloniaList.cs b/src/Avalonia.Base/Collections/AvaloniaList.cs
index 2c7f34c5be..2f1cb2888e 100644
--- a/src/Avalonia.Base/Collections/AvaloniaList.cs
+++ b/src/Avalonia.Base/Collections/AvaloniaList.cs
@@ -280,8 +280,8 @@ namespace Avalonia.Collections
///
/// Gets a range of items from the collection.
///
- /// The first index to remove.
- /// The number of items to remove.
+ /// The zero-based index at which the range starts.
+ /// The number of elements in the range.
public IEnumerable GetRange(int index, int count)
{
return _inner.GetRange(index, count);
@@ -455,7 +455,7 @@ namespace Avalonia.Collections
}
///
- /// Ensures that the capacity of the list is at least .
+ /// Ensures that the capacity of the list is at least .
///
/// The capacity.
public void EnsureCapacity(int capacity)
diff --git a/src/Avalonia.Controls.DataGrid/Collections/DataGridGroupDescription.cs b/src/Avalonia.Controls.DataGrid/Collections/DataGridGroupDescription.cs
index 9d8ebbfac1..587dd228a3 100644
--- a/src/Avalonia.Controls.DataGrid/Collections/DataGridGroupDescription.cs
+++ b/src/Avalonia.Controls.DataGrid/Collections/DataGridGroupDescription.cs
@@ -83,8 +83,9 @@ namespace Avalonia.Collections
if (key == null)
key = item;
- if (_valueConverter != null)
- key = _valueConverter.Convert(key, typeof(object), level, culture);
+ var valueConverter = ValueConverter;
+ if (valueConverter != null)
+ key = valueConverter.Convert(key, typeof(object), level, culture);
return key;
}
@@ -99,6 +100,8 @@ namespace Avalonia.Collections
}
public override string PropertyName => _propertyPath;
+ public IValueConverter ValueConverter { get => _valueConverter; set => _valueConverter = value; }
+
private Type GetPropertyType(object o)
{
return o.GetType().GetNestedPropertyType(_propertyPath);
diff --git a/src/Avalonia.Controls.DataGrid/Utils/CellEditBinding.cs b/src/Avalonia.Controls.DataGrid/Utils/CellEditBinding.cs
index 6ac77fbb99..1d1a595ccf 100644
--- a/src/Avalonia.Controls.DataGrid/Utils/CellEditBinding.cs
+++ b/src/Avalonia.Controls.DataGrid/Utils/CellEditBinding.cs
@@ -1,10 +1,8 @@
using Avalonia.Data;
using Avalonia.Reactive;
using System;
-using System.ComponentModel.DataAnnotations;
using System.Collections.Generic;
using System.Reactive.Subjects;
-using System.Text;
namespace Avalonia.Controls.Utils
{
@@ -67,11 +65,14 @@ namespace Avalonia.Controls.Utils
private void SetSourceValue(object value)
{
- _settingSourceValue = true;
+ if (!_settingSourceValue)
+ {
+ _settingSourceValue = true;
- _sourceSubject.OnNext(value);
+ _sourceSubject.OnNext(value);
- _settingSourceValue = false;
+ _settingSourceValue = false;
+ }
}
private void SetControlValue(object value)
{
@@ -157,4 +158,4 @@ namespace Avalonia.Controls.Utils
}
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Avalonia.Controls/AutoCompleteBox.cs b/src/Avalonia.Controls/AutoCompleteBox.cs
index 5a6e78f441..0e946126ea 100644
--- a/src/Avalonia.Controls/AutoCompleteBox.cs
+++ b/src/Avalonia.Controls/AutoCompleteBox.cs
@@ -2094,7 +2094,21 @@ namespace Avalonia.Controls
bool inResults = !(stringFiltering || objectFiltering);
if (!inResults)
{
- inResults = stringFiltering ? TextFilter(text, FormatValue(item)) : ItemFilter(text, item);
+ if (stringFiltering)
+ {
+ inResults = TextFilter(text, FormatValue(item));
+ }
+ else
+ {
+ if (ItemFilter is null)
+ {
+ throw new Exception("ItemFilter property can not be null when FilterMode has value AutoCompleteFilterMode.Custom");
+ }
+ else
+ {
+ inResults = ItemFilter(text, item);
+ }
+ }
}
if (view_count > view_index && inResults && _view[view_index] == item)
diff --git a/src/Avalonia.Controls/TextBox.cs b/src/Avalonia.Controls/TextBox.cs
index 0eade8d6df..9eae928eeb 100644
--- a/src/Avalonia.Controls/TextBox.cs
+++ b/src/Avalonia.Controls/TextBox.cs
@@ -145,6 +145,18 @@ namespace Avalonia.Controls
(o, v) => o.UndoLimit = v,
unsetValue: -1);
+ public static readonly RoutedEvent CopyingToClipboardEvent =
+ RoutedEvent.Register(
+ "CopyingToClipboard", RoutingStrategies.Bubble);
+
+ public static readonly RoutedEvent CuttingToClipboardEvent =
+ RoutedEvent.Register(
+ "CuttingToClipboard", RoutingStrategies.Bubble);
+
+ public static readonly RoutedEvent PastingFromClipboardEvent =
+ RoutedEvent.Register(
+ "PastingFromClipboard", RoutingStrategies.Bubble);
+
readonly struct UndoRedoState : IEquatable
{
public string Text { get; }
@@ -500,6 +512,24 @@ namespace Avalonia.Controls
}
}
+ public event EventHandler CopyingToClipboard
+ {
+ add => AddHandler(CopyingToClipboardEvent, value);
+ remove => RemoveHandler(CopyingToClipboardEvent, value);
+ }
+
+ public event EventHandler CuttingToClipboard
+ {
+ add => AddHandler(CuttingToClipboardEvent, value);
+ remove => RemoveHandler(CuttingToClipboardEvent, value);
+ }
+
+ public event EventHandler PastingFromClipboard
+ {
+ add => AddHandler(PastingFromClipboardEvent, value);
+ remove => RemoveHandler(PastingFromClipboardEvent, value);
+ }
+
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
{
_presenter = e.NameScope.Get("PART_TextPresenter");
@@ -638,27 +668,54 @@ namespace Avalonia.Controls
public async void Cut()
{
var text = GetSelection();
- if (text is null) return;
+ if (string.IsNullOrEmpty(text))
+ {
+ return;
+ }
- SnapshotUndoRedo();
- Copy();
- DeleteSelection();
+ var eventArgs = new RoutedEventArgs(CuttingToClipboardEvent);
+ RaiseEvent(eventArgs);
+ if (!eventArgs.Handled)
+ {
+ SnapshotUndoRedo();
+ await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)))
+ .SetTextAsync(text);
+ DeleteSelection();
+ }
}
public async void Copy()
{
var text = GetSelection();
- if (text is null) return;
+ if (string.IsNullOrEmpty(text))
+ {
+ return;
+ }
- await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)))
- .SetTextAsync(text);
+ var eventArgs = new RoutedEventArgs(CopyingToClipboardEvent);
+ RaiseEvent(eventArgs);
+ if (!eventArgs.Handled)
+ {
+ await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)))
+ .SetTextAsync(text);
+ }
}
public async void Paste()
{
+ var eventArgs = new RoutedEventArgs(PastingFromClipboardEvent);
+ RaiseEvent(eventArgs);
+ if (eventArgs.Handled)
+ {
+ return;
+ }
+
var text = await ((IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard))).GetTextAsync();
- if (text is null) return;
+ if (string.IsNullOrEmpty(text))
+ {
+ return;
+ }
SnapshotUndoRedo();
HandleTextInput(text);
diff --git a/src/Avalonia.Input/AccessKeyHandler.cs b/src/Avalonia.Input/AccessKeyHandler.cs
index 5c4af68d79..5082265ea6 100644
--- a/src/Avalonia.Input/AccessKeyHandler.cs
+++ b/src/Avalonia.Input/AccessKeyHandler.cs
@@ -157,10 +157,9 @@ namespace Avalonia.Input
_restoreFocusElement?.Focus();
_restoreFocusElement = null;
+
+ e.Handled = true;
}
-
- // We always handle the Alt key.
- e.Handled = true;
}
else if (_altIsDown)
{
diff --git a/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs b/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
index b346fca330..c8bd289e54 100644
--- a/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/AutoCompleteBoxTests.cs
@@ -105,6 +105,16 @@ namespace Avalonia.Controls.UnitTests
});
}
+ [Fact]
+ public void Custom_FilterMode_Without_ItemFilter_Setting_Throws_Exception()
+ {
+ RunTest((control, textbox) =>
+ {
+ control.FilterMode = AutoCompleteFilterMode.Custom;
+ Assert.Throws(() => { control.Text = "a"; });
+ });
+ }
+
[Fact]
public void Text_Completion_Via_Text_Property()
{