Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added AttachedProperty IsDraggable and IsDragHandle + Logic #178

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

NoizeDaemon
Copy link

@NoizeDaemon NoizeDaemon commented Oct 20, 2024

Hey, this is my first pull request ever 😬
I'll appreciate any feedback!

Also thank you for this awesome library and all the great work you do in general for Avalonia!


Summary

I needed more control over when a control can be dragged and where it needs to be clicked on to be dragged.

To accomplish this I introduced two AttachedProperty on CanvasDragBehavior:

  • CanvasDragBehavior.IsDraggable can be set directly on the draggable Control to change it's draggability.
  • CanvasDragBehavior.IsDragHandle can be set on any number of descendants of the draggable Control.
    • If IsDragHandle is not set on any descendant, the whole draggable Control acts as draghandle (current behavior).
    • If IsDragHandle is set on at least one descendant, the draggable control can only be moved by cicking those descendants.

To showcase these properties in action, I added Canvas (Advanced)-tab to the DraggableDemo-Project:
image

How does it work?

IsDraggable

// Set _rootControl in OnLoaded() 
_rootControl = AssociatedObject is ContentPresenter presenter ? presenter.Child : AssociatedObject;
...

// Check draggability in Pressed()
_rootControl?.GetValue(IsDraggableProperty) == true
...

IsDragHandle

The approach of setting the property directly on the descendant required moving some of the logic in OnAttachedToVisualTree() to OnLoaded(), since the GetVisualDescendants() won't get any/all descendants when called from the former.

            _dragHandles = AssociatedObject.GetVisualDescendants().Where(d => d.GetValue(IsDragHandleProperty));

            if (_dragHandles.Any())
            {
                foreach (Control dragHandle in _dragHandles)
                {
                    // Add PointerEvent-Handlers to dragHandle instead of AssociatedObject
                }
            }
            else
            {
                // Add PointerEvent-Handlers to AssociatedControl
            }

Dependency on Linq

I am using Where() and Any() in the draghandle logic, since GetVisualDescendants() returns an IEnumerable.
Should I use ToList() instead and loop over its elements to avoid the the Linq dependency, or does that not matter?

- `CanvasDragBevahior.IsDraggable` can be set directly on the draggable Control to change it's draggability.
- `CanvasDragBehaviors.IsDragHandle` can be set on any number of descendants of the draggable Control.
    - If `IsDragHandle` is not set on any descendant, the whole draggable Control acts as draghandle.
    -  If `IsDragHandle` is set on at least one descendant, the draggable control can only be moved by cicking those descendants.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant