Browse Source

Merge branch 'master' into fixes/osx-dialog-keep-on-top-when-deactivated

pull/8211/head^2
Dan Walmsley 4 years ago
committed by GitHub
parent
commit
ff07d2069c
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 9
      src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs
  2. 5
      src/Avalonia.Controls/ContextMenu.cs
  3. 3
      src/Avalonia.Controls/Flyouts/FlyoutBase.cs
  4. 10
      src/Web/Avalonia.Web.Blazor/AvaloniaView.razor
  5. 103
      src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs
  6. 21
      tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs
  7. 25
      tests/Avalonia.Controls.UnitTests/FlyoutTests.cs
  8. 32
      tests/Avalonia.Markup.UnitTests/Data/BindingTests_Method.cs

9
src/Avalonia.Base/Data/Converters/DefaultValueConverter.cs

@ -33,7 +33,14 @@ namespace Avalonia.Data.Converters
if (typeof(ICommand).IsAssignableFrom(targetType) && value is Delegate d && d.Method.GetParameters().Length <= 1)
{
return new MethodToCommandConverter(d);
if (d.Method.IsPrivate == false)
{
return new MethodToCommandConverter(d);
}
else
{
return new BindingNotification(new InvalidCastException("You can't bind to private methods!"), BindingErrorType.Error);
}
}
if (TypeUtilities.TryConvert(targetType, value, culture, out var result))

5
src/Avalonia.Controls/ContextMenu.cs

@ -450,6 +450,11 @@ namespace Avalonia.Controls
if (sender is Control control
&& control.ContextMenu is ContextMenu contextMenu)
{
if (contextMenu._popup?.Parent == control)
{
((ISetLogicalParent)contextMenu._popup).SetParent(null);
}
contextMenu.Close();
}
}

3
src/Avalonia.Controls/Flyouts/FlyoutBase.cs

@ -175,7 +175,8 @@ namespace Avalonia.Controls.Primitives
IsOpen = false;
Popup.IsOpen = false;
((ISetLogicalParent)Popup).SetParent(null);
// Ensure this isn't active
_transientDisposable?.Dispose();
_transientDisposable = null;

10
src/Web/Avalonia.Web.Blazor/AvaloniaView.razor

@ -1,14 +1,12 @@
<div id="container" class="avalonia-container" tabindex="0" oncontextmenu="return false;"
ontouchstart="@OnTouchStart"
ontouchend="@OnTouchEnd"
ontouchcancel="@OnTouchCancel"
ontouchmove="@OnTouchMove"
onmousemove="@OnMouseMove"
onmousedown="@OnMouseDown"
onmouseup="@OnMouseUp"
onwheel="@OnWheel"
onkeydown="@OnKeyDown"
onkeyup="@OnKeyUp">
onkeyup="@OnKeyUp"
onpointerdown="@OnPointerDown"
onpointerup="@OnPointerUp"
onpointermove="@OnPointerMove">
<canvas id="htmlCanvas" @ref="_htmlCanvas" @attributes="AdditionalAttributes"/>

103
src/Web/Avalonia.Web.Blazor/AvaloniaView.razor.cs

@ -56,90 +56,91 @@ namespace Avalonia.Web.Blazor
{
return _nativeControlHost ?? throw new InvalidOperationException("Blazor View wasn't initialized yet");
}
private void OnTouchStart(TouchEventArgs e)
private void OnTouchCancel(TouchEventArgs e)
{
foreach (var touch in e.ChangedTouches)
{
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchBegin, new Point(touch.ClientX, touch.ClientY),
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchCancel, new Point(touch.ClientX, touch.ClientY),
GetModifiers(e), touch.Identifier);
}
}
private void OnTouchEnd(TouchEventArgs e)
private void OnTouchMove(TouchEventArgs e)
{
foreach (var touch in e.ChangedTouches)
{
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchEnd, new Point(touch.ClientX, touch.ClientY),
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchUpdate, new Point(touch.ClientX, touch.ClientY),
GetModifiers(e), touch.Identifier);
}
}
private void OnTouchCancel(TouchEventArgs e)
private void OnPointerMove(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
foreach (var touch in e.ChangedTouches)
if (e.PointerType != "touch")
{
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchCancel, new Point(touch.ClientX, touch.ClientY),
GetModifiers(e), touch.Identifier);
_topLevelImpl.RawMouseEvent(RawPointerEventType.Move, new Point(e.ClientX, e.ClientY), GetModifiers(e));
}
}
private void OnTouchMove(TouchEventArgs e)
private void OnPointerUp(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
foreach (var touch in e.ChangedTouches)
if (e.PointerType == "touch")
{
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchUpdate, new Point(touch.ClientX, touch.ClientY),
GetModifiers(e), touch.Identifier);
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchEnd, new Point(e.ClientX, e.ClientY),
GetModifiers(e), e.PointerId);
}
}
private void OnMouseMove(MouseEventArgs e)
{
_topLevelImpl.RawMouseEvent(RawPointerEventType.Move, new Point(e.ClientX, e.ClientY), GetModifiers(e));
}
else
{
RawPointerEventType type = default;
private void OnMouseUp(MouseEventArgs e)
{
RawPointerEventType type = default;
switch (e.Button)
{
case 0:
type = RawPointerEventType.LeftButtonUp;
break;
switch (e.Button)
{
case 0:
type = RawPointerEventType.LeftButtonUp;
break;
case 1:
type = RawPointerEventType.MiddleButtonUp;
break;
case 1:
type = RawPointerEventType.MiddleButtonUp;
break;
case 2:
type = RawPointerEventType.RightButtonUp;
break;
}
case 2:
type = RawPointerEventType.RightButtonUp;
break;
_topLevelImpl.RawMouseEvent(type, new Point(e.ClientX, e.ClientY), GetModifiers(e));
}
_topLevelImpl.RawMouseEvent(type, new Point(e.ClientX, e.ClientY), GetModifiers(e));
}
private void OnMouseDown(MouseEventArgs e)
private void OnPointerDown(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
RawPointerEventType type = default;
switch (e.Button)
if (e.PointerType == "touch")
{
case 0:
type = RawPointerEventType.LeftButtonDown;
break;
_topLevelImpl.RawTouchEvent(RawPointerEventType.TouchBegin, new Point(e.ClientX, e.ClientY),
GetModifiers(e), e.PointerId);
}
else
{
RawPointerEventType type = default;
switch (e.Button)
{
case 0:
type = RawPointerEventType.LeftButtonDown;
break;
case 1:
type = RawPointerEventType.MiddleButtonDown;
break;
case 1:
type = RawPointerEventType.MiddleButtonDown;
break;
case 2:
type = RawPointerEventType.RightButtonDown;
break;
}
case 2:
type = RawPointerEventType.RightButtonDown;
break;
}
_topLevelImpl.RawMouseEvent(type, new Point(e.ClientX, e.ClientY), GetModifiers(e));
_topLevelImpl.RawMouseEvent(type, new Point(e.ClientX, e.ClientY), GetModifiers(e));
}
}
private void OnWheel(WheelEventArgs e)
@ -189,7 +190,7 @@ namespace Avalonia.Web.Blazor
return modifiers;
}
private static RawInputModifiers GetModifiers(MouseEventArgs e)
private static RawInputModifiers GetModifiers(Microsoft.AspNetCore.Components.Web.PointerEventArgs e)
{
var modifiers = RawInputModifiers.None;

21
tests/Avalonia.Controls.UnitTests/ContextMenuTests.cs

@ -446,6 +446,27 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Should_Reset_Popup_Parent_On_Target_Detached()
{
using (Application())
{
var userControl = new UserControl();
var window = PreparedWindow(userControl);
window.Show();
var menu = new ContextMenu();
userControl.ContextMenu = menu;
menu.Open();
var popup = Assert.IsType<Popup>(menu.Parent);
Assert.NotNull(popup.Parent);
window.Content = null;
Assert.Null(popup.Parent);
}
}
[Fact]
public void Context_Menu_In_Resources_Can_Be_Shared()
{

25
tests/Avalonia.Controls.UnitTests/FlyoutTests.cs

@ -432,6 +432,26 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Should_Reset_Popup_Parent_On_Target_Detached()
{
using (CreateServicesWithFocus())
{
var userControl = new UserControl();
var window = PreparedWindow(userControl);
window.Show();
var flyout = new TestFlyout();
flyout.ShowAt(userControl);
var popup = Assert.IsType<Popup>(flyout.Popup);
Assert.NotNull(popup.Parent);
window.Content = null;
Assert.Null(popup.Parent);
}
}
[Fact]
public void ContextFlyout_Can_Be_Set_In_Styles()
{
@ -549,5 +569,10 @@ namespace Avalonia.Controls.UnitTests
new PointerPointProperties(RawInputModifiers.None, PointerUpdateKind.LeftButtonPressed),
KeyModifiers.None);
}
public class TestFlyout : Flyout
{
public new Popup Popup => base.Popup;
}
}
}

32
tests/Avalonia.Markup.UnitTests/Data/BindingTests_Method.cs

@ -0,0 +1,32 @@
using Avalonia.Controls;
using Avalonia.Data;
using Avalonia.Input;
using Avalonia.Interactivity;
using Xunit;
namespace Avalonia.Markup.UnitTests.Data
{
public class BindingTests_Method
{
[Fact]
public void Binding_To_Private_Methods_Shouldnt_Work()
{
var vm = new TestClass();
var target = new Button
{
DataContext = vm,
[!Button.CommandProperty] = new Binding("MyMethod"),
};
target.RaiseEvent(new RoutedEventArgs(AccessKeyHandler.AccessKeyPressedEvent));
Assert.False(vm.IsSet);
}
class TestClass
{
public bool IsSet { get; set; }
private void MyMethod() => IsSet = true;
}
}
}
Loading…
Cancel
Save