How to make a movable control in Avalonia?

Abdella Solomon
3 min readMar 20, 2022

--

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.

--

--