<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: François Raminosona</title>
    <description>The latest articles on DEV Community by François Raminosona (@framinosona).</description>
    <link>https://dev.to/framinosona</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F390552%2F3f1f9afd-b449-42a3-a935-97e4f3f050c6.jpg</url>
      <title>DEV Community: François Raminosona</title>
      <link>https://dev.to/framinosona</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/framinosona"/>
    <language>en</language>
    <item>
      <title>ByteArrayConverter</title>
      <dc:creator>François Raminosona</dc:creator>
      <pubDate>Wed, 20 May 2020 12:27:16 +0000</pubDate>
      <link>https://dev.to/framinosona/bytearrayconverter-3n78</link>
      <guid>https://dev.to/framinosona/bytearrayconverter-3n78</guid>
      <description>&lt;h2&gt;
  
  
  My Final Project
&lt;/h2&gt;

&lt;p&gt;I've written a little Nuget package converting a byte array to anything and back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Link to Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vWogaON8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-28d89282e0daa1e2496205e2f218a44c755b0dd6536bbadf5ed5a44a7ca54716.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/framinosona"&gt;
        framinosona
      &lt;/a&gt; / &lt;a href="https://github.com/framinosona/ByteArrayConverter"&gt;
        ByteArrayConverter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer" href="https://raw.githubusercontent.com/framinosona/ByteArrayConverter/master/Images/Banner.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fMP1LTH---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://raw.githubusercontent.com/framinosona/ByteArrayConverter/master/Images/Banner.png" alt="Banner"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;
ByteArrayConverter&lt;/h1&gt;
&lt;p&gt;Here is a little nuget about byte array conversion&lt;/p&gt;
&lt;/div&gt;



&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/framinosona/ByteArrayConverter"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;Using CSharp&lt;/p&gt;

</description>
      <category>octograd2020</category>
    </item>
    <item>
      <title>Drag and drop in Xamarin.Forms</title>
      <dc:creator>François Raminosona</dc:creator>
      <pubDate>Thu, 10 Oct 2019 12:00:00 +0000</pubDate>
      <link>https://dev.to/framinosona/drag-and-drop-in-xamarin-forms-fixed-for-android-4bk1</link>
      <guid>https://dev.to/framinosona/drag-and-drop-in-xamarin-forms-fixed-for-android-4bk1</guid>
      <description>&lt;p&gt;In this article I will be showing you how to add a Drag and Drop interaction in your Xamarin.Forms app. I won't use any native component or Custom Renderer on purpose, many of these solutions are available elsewhere (see &lt;strong&gt;&lt;em&gt;&lt;a href="https://blog.francois.raminosona.com/drag-and-drop-solutions-in-xamarin"&gt;Drag and Drop solutions for Xamarin&lt;/a&gt;&lt;/em&gt;&lt;/strong&gt;). I'll be using PanGestureRecognizer, TranslateTo and some basic maths.&lt;/p&gt;

&lt;p&gt;All the code I'm about to explain here is available on my &lt;a href="https://github.com/framinosona/Xamarin-Developer-Sample/tree/master/DeveloperSample.Core/Pages/DragAndDrop/Sample3"&gt;&lt;strong&gt;Developer Playground on Github&lt;/strong&gt;&lt;/a&gt;. Feel free to check it out.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/framinosona/Xamarin-Developer-Sample/tree/master/DeveloperSample.Core/Pages/DragAndDrop/Sample1"&gt;1- PanGestureRecognizer&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The Sample 1 page let's you play with the PanGestureRecognizer and the data it sends. A pan gesture is a gesture where the user puts at least one finger down and drags it from a point A to a point B then releases it. This gesture fits perfectly what we want to do.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ox9tib-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.francois.raminosona.com/content/images/2019/06/IMG_9410-squashed.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ox9tib-M--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://blog.francois.raminosona.com/content/images/2019/06/IMG_9410-squashed.jpeg" alt="Drag and drop in Xamarin.Forms (Fixed for Android)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/framinosona/Xamarin-Developer-Sample/tree/master/DeveloperSample.Core/Pages/DragAndDrop/Sample1"&gt;This sample&lt;/a&gt; shows you that :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;_PanUpdatedEventArgs. &lt;strong&gt;TotalX&lt;/strong&gt; _ and _PanUpdatedEventArgs. &lt;strong&gt;TotalY&lt;/strong&gt; _ are delta distances between start and end of the pan gesture&lt;/li&gt;
&lt;li&gt;If you initiate 2 gestures at the same time the _PanUpdatedEventArgs. &lt;strong&gt;GestureId&lt;/strong&gt; _ might be the same, &lt;strong&gt;do not use as ID&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;_PanUpdatedEventArgs. &lt;strong&gt;StatusType&lt;/strong&gt; _ has one of the following values : Canceled, Completed, Running or Started&lt;/li&gt;
&lt;li&gt;When 2 views are overlapping, with each having a gesture recognizer, the top level one captures the gesture and the bottom one doesn't&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://github.com/framinosona/Xamarin-Developer-Sample/tree/master/DeveloperSample.Core/Pages/DragAndDrop/Sample2"&gt;2- Moving the view around&lt;/a&gt;
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2.1- View.TranslateTo(X,Y);
&lt;/h3&gt;

&lt;p&gt;Now that we know how to read the information from a PanGesture, we need to move the drag and droppable view accordingly. For this I use TranslateTo() because it only moves the interface, the element itself thinks he doesn't move. No need to "Redraw" or call "InvalidateLayout".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Rz6ylORL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.francois.raminosona.com/content/images/2019/06/Sample2-2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Rz6ylORL--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.francois.raminosona.com/content/images/2019/06/Sample2-2.gif" alt="Drag and drop in Xamarin.Forms (Fixed for Android)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here you can play with the duration of the animation, in milliseconds. If you want to add a delay or make the ui fade out when the drag and drop ends, this is the place.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2- GetScreenCoordinates();
&lt;/h3&gt;

&lt;p&gt;We want to be able to know where our view is located in the screen. Since we don't actually move it we need a way to calculate these coordinates. We need many values to calculate that :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Distance from the &lt;em&gt;Top of the screen&lt;/em&gt; to the &lt;em&gt;Top of the view&lt;/em&gt; before pan &lt;/li&gt;
&lt;li&gt;Distance from the &lt;em&gt;Left of the screen&lt;/em&gt; to the &lt;em&gt;Left of the view&lt;/em&gt; before pan&lt;/li&gt;
&lt;li&gt;Pan distance horizontally : &lt;strong&gt;e.TotalX&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Pan distance vertically : &lt;strong&gt;e.TotalY&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Distance from the &lt;em&gt;Left of the view&lt;/em&gt; to the &lt;em&gt;Center of the view&lt;/em&gt; : &lt;strong&gt;Width / 2&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Distance from the &lt;em&gt;Top of the view&lt;/em&gt; to the &lt;em&gt;Center of the view&lt;/em&gt; : &lt;strong&gt;Height / 2&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To get the first two, I found a comment from Dan Meier (&lt;a href="https://twitter.com/factoryoptimizr"&gt;@FactoryOptimizr&lt;/a&gt;) on the &lt;a href="https://forums.xamarin.com/discussion/66386/how-to-get-the-coordinates-where-there-is-a-control-on-the-screen"&gt;Xamarin's forum&lt;/a&gt; :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/// &amp;lt;summary&amp;gt;
/// Gets the screen coordinates from top left corner.
/// &amp;lt;/summary&amp;gt;
/// &amp;lt;returns&amp;gt;The screen coordinates.&amp;lt;/returns&amp;gt;
/// &amp;lt;param name="view"&amp;gt;View.&amp;lt;/param&amp;gt;
public static (double X, double Y) GetScreenCoordinates(this VisualElement view)
{
    // A view's default X- and Y-coordinates are LOCAL with respect to the boundaries of its parent,
    // and NOT with respect to the screen. This method calculates the SCREEN coordinates of a view.
    // The coordinates returned refer to the top left corner of the view.

    // Initialize with the view's "local" coordinates with respect to its parent
    double screenCoordinateX = view.X;
    double screenCoordinateY = view.Y;

    // Get the view's parent (if it has one...)
    if (view.Parent.GetType() != typeof(App))
    {
        VisualElement parent = (VisualElement) view.Parent;

        // Loop through all parents
        while (parent != null)
        {
            // Add in the coordinates of the parent with respect to ITS parent
            screenCoordinateX += parent.X;
            screenCoordinateY += parent.Y;

            // If the parent of this parent isn't the app itself, get the parent's parent.
            if (parent.Parent.GetType() == typeof(App))
                parent = null;
            else
                parent = (VisualElement) parent.Parent;
        }
    }

    // Return the final coordinates...which are the global SCREEN coordinates of the view
    return (screenCoordinateX, screenCoordinateY);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Thank you for that Dan ! 😉&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/framinosona/Xamarin-Developer-Sample/blob/master/DeveloperSample.Core/Helpers/ViewExtensions.cs"&gt;[Check out this file on Github]&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This allows us to calculate the screen coordinates :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var screenCoordinates = this.GetScreenCoordinates();
var xPosition = screenCoordinates.X + e.TotalX + Width / 2;
var yPosition = screenCoordinates.Y + e.TotalY + Height / 2;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;a href="https://github.com/framinosona/Xamarin-Developer-Sample/tree/master/DeveloperSample.Core/Pages/DragAndDrop/Sample3"&gt;3- Bringing it all together&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;A full Drag and Drop interaction requires events to be sent from the moving views to one or many receiving views.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1- Receiving View
&lt;/h3&gt;

&lt;p&gt;The receiving view will be the view reacting to some other view drag and dropping. I made &lt;em&gt;IDragAndDropHoverableView&lt;/em&gt; and &lt;em&gt;IDragAndDropReceivingView&lt;/em&gt; for that :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface IDragAndDropHoverableView
{
    void OnHovered(List&amp;lt;IDragAndDropMovingView&amp;gt; views);
}

public interface IDragAndDropReceivingView
{
    void OnDropReceived(IDragAndDropMovingView view);
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note that it can be hovered by many views at once, hence the &lt;em&gt;List&amp;lt;&amp;gt;&lt;/em&gt; of views in the parameters. For Drop on the other hand I want to take care of drops separately.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.2- Moving View
&lt;/h3&gt;

&lt;p&gt;The moving view is the view that ... is moving! From that view we need to have the position of the centre (X,Y) available :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public interface IDragAndDropMovingView
{
    double ScreenX { get; set; }
    double ScreenY { get; set; }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To initialise that view I decided to make it an extension method, so it can be called from different types of moving views. It is useful if you want to drag and drop an image, a button, a video, a frame ... anything.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public class DragAndDropSample3MovingView : Frame, IDragAndDropMovingView
{
    public double ScreenX { get; set; }
    public double ScreenY { get; set; }

    protected override void OnParentSet()
    {
        base.OnParentSet();
        this.InitializeDragAndDrop();
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3- Drag and drop Container
&lt;/h3&gt;

&lt;p&gt;In order to manage all this we need a container. In order to know chat can interact with what. For this reason I added the function &lt;em&gt;GetContainer()&lt;/em&gt; that goes through all parent views looking for an element of type &lt;em&gt;IDragAndDropContainer&lt;/em&gt; of, if none is found, a &lt;em&gt;Page&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static VisualElement GetContainer(this IDragAndDropMovingView view)
{
    if (!(view is VisualElement visualElement))
        throw new Exception($"{nameof(IDragAndDropMovingView)} can only be an interface on a {nameof(View)}");
    var dropContainer = visualElement.GetFirstParentOfType&amp;lt;IDragAndDropContainer&amp;gt;();
    if (dropContainer is VisualElement output) return output;
    return visualElement.GetFirstParentOfType&amp;lt;Page&amp;gt;();
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3.4- Get all children of type T in View
&lt;/h3&gt;

&lt;p&gt;We need to retrieve all the subviews, children that match the type given in order to get all the receiving or moving views from the container :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static List&amp;lt;T&amp;gt; GetAllChildrenOfType&amp;lt;T&amp;gt;(this Element view)
{
    if (view is ContentPage page) view = page.Content;

    var output = new List&amp;lt;T&amp;gt;();

    if (view is T tview)
        output.Add(tview);

    if (view is Layout layout)
        foreach (var child in layout.Children)
            if (child is Element elementChild)
                output.AddRange(elementChild.GetAllChildrenOfType&amp;lt;T&amp;gt;());

    return output;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3.5- GetFirstParentOfType();
&lt;/h3&gt;

&lt;p&gt;If we put all our drag and drop components inside a container, we need those components to crawl up the view-tree to reach that container. Here is an extension function that does that :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public static T GetFirstParentOfType&amp;lt;T&amp;gt;(this Element view)
{
    Element output = view;
    while (output.Parent != null)
    {
        if (output.Parent is T parent)
            return parent;
        output = output.Parent;
    }

    return default;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3.6- UpdateHoverStatuses();
&lt;/h3&gt;

&lt;p&gt;When the moving views are moving, you can see (at the bottom of &lt;em&gt;PanGestureRecognizer_PanUpdated&lt;/em&gt;) that they call &lt;em&gt;UpdateHoverStatuses()&lt;/em&gt; on the container. This makes the container to recalculate which view is on top of which and to send that information to the receiving views :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static void UpdateHoverStatuses(this VisualElement view)
{
    var allReceivers = view.GetAllChildrenOfType&amp;lt;IDragAndDropHoverableView&amp;gt;();
    var allSenders = view.GetAllChildrenOfType&amp;lt;IDragAndDropMovingView&amp;gt;();

    foreach (var receiver in allReceivers)
    {
        if (!(receiver is VisualElement veReceiver)) continue;
        var x = veReceiver.GetScreenCoordinates().X;
        var y = veReceiver.GetScreenCoordinates().Y;
        var width = veReceiver.Width;
        var height = veReceiver.Height;
        receiver.OnHovered(allSenders.Where(sender =&amp;gt; sender.ScreenX &amp;gt;= x &amp;amp;&amp;amp;
                                                        sender.ScreenX &amp;lt;= x + width &amp;amp;&amp;amp;
                                                        sender.ScreenY &amp;gt;= y &amp;amp;&amp;amp;
                                                        sender.ScreenY &amp;lt;= y + height
        ).ToList());
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  3.7- DragAndDroppableViewDropped(IDragAndDropMovingView);
&lt;/h3&gt;

&lt;p&gt;We also want the container to forward the information to receiving views when a moving view is dropped. Because there might be multiple views underneath I'm sending the info to every receiving view that matches :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;private static void DragAndDroppableViewDropped(this VisualElement view, IDragAndDropMovingView sender)
{
    var allReceivers = view.GetAllChildrenOfType&amp;lt;IDragAndDropReceivingView&amp;gt;();

    foreach (var receiver in allReceivers)
    {
        if (!(receiver is VisualElement veReceiver)) continue;
        var x = veReceiver.GetScreenCoordinates().X;
        var y = veReceiver.GetScreenCoordinates().Y;
        var width = veReceiver.Width;
        var height = veReceiver.Height;
        if (sender.ScreenX &amp;gt;= x &amp;amp;&amp;amp;
            sender.ScreenX &amp;lt;= x + width &amp;amp;&amp;amp;
            sender.ScreenY &amp;gt;= y &amp;amp;&amp;amp;
            sender.ScreenY &amp;lt;= y + height)
            receiver.OnDropReceived(sender);
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Result
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--P0BtkzQ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.francois.raminosona.com/content/images/2019/06/Sample-3-2.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P0BtkzQ3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_66%2Cw_880/https://blog.francois.raminosona.com/content/images/2019/06/Sample-3-2.gif" alt="Drag and drop in Xamarin.Forms (Fixed for Android)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/framinosona/Xamarin-Developer-Sample"&gt;[The source code is available on my Github]&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Let me know if it helped you! 😀&lt;/p&gt;

</description>
      <category>mobile</category>
      <category>net</category>
      <category>xamarin</category>
      <category>xamarinios</category>
    </item>
  </channel>
</rss>
