Last active
February 6, 2022 10:58
-
-
Save softlion/5a845180c51b90c8624187273cef9193 to your computer and use it in GitHub Desktop.
Xamarin Forms get absolute bounds of a control and display a menu at this location
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Vapolia | |
{ | |
public interface IScreenLocation | |
{ | |
PointF GetCoordinates(VisualElement view); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//using Vapolia.UserInteraction | |
public ICommand OpenMenuCommand => MakeCommand<VisualElement>(async sourceView => | |
{ | |
var bounds = ThisControlExtension.GetAbsoluteBounds(sourceView); | |
var action = await UserInteraction.Menu(CancellationToken.None, true, bounds, null, null, -1, "Cancel", "Remove", "Rename", "Copy", "Open"); | |
//if(action == 1) ... | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ContentPage ... x:Name="ThePage"> | |
<Button Text="My Button" | |
Command="{Binding SomeCommand,Source={x:Reference ThePage}}" | |
CommandParameter="{vapolia:ThisControl}" /> | |
</ContentPage> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.Android; | |
[assembly:Dependency(typeof(Vapolia.Droid.ScreenLocation))] | |
namespace Vapolia.Droid | |
{ | |
public class ScreenLocation : IScreenLocation | |
{ | |
public System.Drawing.PointF GetCoordinates(VisualElement element) | |
{ | |
var renderer = Platform.GetRenderer(element); | |
var nativeView = renderer.View; | |
var density = nativeView.Context!.Resources!.DisplayMetrics!.Density; | |
var locationWindow = new int[2]; | |
nativeView.GetLocationInWindow(locationWindow); | |
var locationOfRootWindow = new int[2]; | |
nativeView.RootView.FindViewById(Android.Resource.Id.Content).GetLocationInWindow(locationOfRootWindow); | |
return new System.Drawing.PointF(locationWindow[0] / density, (locationWindow[1]-locationOfRootWindow[1]) / density); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Xamarin.Forms; | |
using Xamarin.Forms.Platform.iOS; | |
[assembly:Dependency(typeof(Vapolia.iOS.ScreenLocation))] | |
namespace Vapolia.iOS | |
{ | |
public class ScreenLocation : IScreenLocation | |
{ | |
public System.Drawing.PointF GetCoordinates(VisualElement element) | |
{ | |
var renderer = Platform.GetRenderer(element); | |
var nativeView = renderer.NativeView; | |
var rect = nativeView.Superview.ConvertPointToView(nativeView.Frame.Location, null); | |
return new System.Drawing.PointF((float)rect.X, (float)rect.Y); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Vapolia | |
{ | |
/// <summary> | |
/// Sample Usage: | |
/// <Button Text="Click Me" Command="{Binding SomeCommand}" CommandParameter="{Binding Source={vapolia:ThisControl}}" /> | |
/// </summary> | |
public sealed class ThisControlExtension : IMarkupExtension<VisualElement> | |
{ | |
public VisualElement ProvideValue(IServiceProvider sp) | |
{ | |
var target = (IProvideValueTarget)sp.GetService(typeof(IProvideValueTarget)); | |
return (VisualElement)target.TargetObject; | |
} | |
object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) => ProvideValue(serviceProvider); | |
public static RectangleF GetAbsoluteBounds(VisualElement view) | |
{ | |
var screenLocation = DependencyService.Get<IScreenLocation>(); | |
var pos = screenLocation.GetCoordinates(view); | |
return new(pos.X, pos.Y, (float)view.Width, (float)view.Height); | |
} | |
}; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment