How to make a movable control in Avalonia?

Prerequisites- This article assumes a basic understanding of the Avalonia framework.

How do controls work?

The “Control” class is an essential class that inherits from the InputElement class and the IControl interface. Of course, it inherits a lot more dependencies but these are the main ones. So, the Control class is a layer for a lot of other top layer controls like Button, Border, etc …

This Control class provides these top layer controls with events, methods, and properties that they require to function. For our purpose, we will work with the mouse pressing, releasing, and moving events.

How to make custom controls?

Custom controls are a good choice when we are trying to modify a certain behavior of a control. We wrap the existing controls in our custom control(In a sense a “class”) then we do our modification inside our custom control.

We’re going to make a movable control. So, to make things compulsory, let’s work with the Border control so that we can use our custom border as a container for the controls we want to move around. Let’s create the custom class now.

Let’s create a new .cs file called “CustomMovableControl” or you can name it whatever you want and create our class there.

public class CustomMovableBorder : Border
{
/* We will do our modification here */
}

As you can see on the above lines of code, the CustomMovableBorder is inheriting from the Border class. This Border class is a class that inherits the Control class. So now, our CustomMovableBorder can do everything that Border control can do.

How to work with mouse pointer?

So far, we discussed how controls work and made our own custom control from the Border control. Like I said earlier, our CustomMovableBorder has all properties of the Border class and in a sense the Control class. If you look into the Control class from the documentation, you can see that there are a lot of events and properties. From all that properties and events, we are only going to work with the PointerPressed, PointerReleased, and PointerMoved events. These events are mouse-related events.

  • PointerPressed get’s fired when we press the left click of our mouse over the control.
  • PointerReleased get’s fired when we release(leave) the left click of our mouse over the control.
  • PointerMoved get’s fired when we move the mouse pointer over the control.

The above events are connected with their pair methods: OnPointerPressed, OnPointerReleased, and OnPointerMoved methods. So, let’s override these methods in our class.

public class CustomMovableBorder : Border
{
protected override void OnPointerPressed(PointerPressedEventArgs e)
{

base.OnPointerPressed(e);
}
protected override void OnPointerReleased(PointerReleasedEventArgs e)
{

base.OnPointerReleased(e);
}
protected override void OnPointerMoved(PointerEventArgs e)
{

base.OnPointerMoved(e);
}
}

We need 3 of these methods to make our custom movable control work. Of course, we can only use the OnPointerMoved method but we want to detect mouse released and pressed events too. So, to make the whole thing function we need three more new properties.

  1. A property to detect if the mouse left click is pressed or not. It will be a type of bool.
  2. A property to save the previous position of the mouse pointer in memory. It will be a type of Point.
  3. A property to save the previous position of the control in the parent control in memory. It will be a type of TranslateTransform.

So, finally, the whole code using the above properties will look something like this:

The full source code can be found here.

A working example of CustomMovableControl

Follow me on Medium to get notified of my new articles!

Show me some love by following me on Twitter and Github. If you have any questions or feedback, shoot it in the comment section.

--

--

--

A 17yo programmer | Calculus lover | Machine learning enthusiastic | Writer | Freelancer | Lecturer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

The Graph — an overview of the project

Infra As Code — Add Worknodes To AWS EKS Cluster Using Terraform

Introducing Govbase

How to install and configure printers on Kali Linux

Database, Entity Framework -2

Thread Synchronization and ThreadLocal in Java

Connect to Box, SharePoint, Dropbox via S3

Settings screen in Android Studio with the new AndroidX Preference library

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Abdella Solomon

Abdella Solomon

A 17yo programmer | Calculus lover | Machine learning enthusiastic | Writer | Freelancer | Lecturer

More from Medium

Write a code to retrieve data from table into a datagridview in CSharp

ASP.NET Core Multilanguage Done Simple

Building a Cross Platform NuGet Package

Testing file upload with Swagger in ASP.Net core