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 LambdaDragHandler and -DropHandler #294

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

Added LambdaDragHandler and -DropHandler #294

wants to merge 1 commit into from

Conversation

Yeah69
Copy link

@Yeah69 Yeah69 commented Jul 8, 2018

What changed?

Similar to the IValueConverters in the LambdaConverter-project the DropHandlers (IDropTarget) and the DragHandlers (IDragSource) could be implemented more conveniently with the "Lambda"-pattern.

Instead of writing a whole class the LambdaHandlers let you implement a handler by passing appropriate Actions and Funcs. All Action- and Func-parameters are optional, hence in cases where a function would be left empty in the implementation, the parameter can just be left out. If assigned to static fields or properties the LamdaHandlers can be referenced via x:Static in Xaml-code. All in all the LambdaHandlers make the implementations of IDropTarget and IDragSource shorter and more convenient to use.

@Yeah69
Copy link
Author

Yeah69 commented Mar 29, 2019

@punker76 So, did you have a look into my pull request? It is nearly a year open and no reaction. If you don't like it, then we could just close it. No problem.
But I don't like to leave it hanging here.

@punker76
Copy link
Owner

@Yeah69 I'm so Sorry! Yes I looked into this PR but I didn't understand correctly why I need this (then I forgot to ask). It looked like that this was/is only a wrapper around already existing functionality. It would be nice if you can show me with an example what the benefit of this is and why it should be added in the library itself? thx in advance!

@Yeah69
Copy link
Author

Yeah69 commented Mar 30, 2019

@punker76 Take SampleData and GroupedDropHandler from the project Showcase.WPF.DragDrop.NET45 for an example. The class GroupedDropHandler is used only in SampleData. I don't think it is that way, but let's - for the sake of my argument - imagine that GroupedDropHandler because of its one-time-use has logic specific for SampleData. That would mean that the logic of SampleData is scattered over the solution. In the current situation it is understandable why. Because the SampleData chose composition over inheritance (implementing IDropTarget itself). So another class has to implement it and so a separated file has to be created. With my suggestion in the PR you wouldn't need the overhead of yet another class with the sole purpose of acting as a container for some logic and the overhead of a file per drop handler.
Coming back to the SampleData and GroupedDropHandler you could just create your IDropTarget-instance in place:

this.GroupedDropHandler = LambdaDropHandler.Create(
                di =>
                {
                    // Call default DragOver method, cause most stuff should work by default
                    GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.DragOver(di);
                    if (di.TargetGroup == null)
                    {
                        di.Effects = System.Windows.DragDropEffects.None;
                    }
                },
                di =>
                {
                    // The default drop handler don't know how to set an item's group. You need to explicitly set the group on the dropped item like this.
                    GongSolutions.Wpf.DragDrop.DragDrop.DefaultDropHandler.Drop(di);

                    // Now extract the dragged group items and set the new group (target)
                    var data = DefaultDropHandler.ExtractData(di.Data).OfType<GroupedItem>().ToList();
                    foreach (var groupedItem in data)
                    {
                        groupedItem.Group = di.TargetGroup.Name.ToString();
                    }

                    // Changing group data at runtime isn't handled well: force a refresh on the collection view.
                    if (di.TargetCollection is ICollectionView)
                    {
                        ((ICollectionView)di.TargetCollection).Refresh();
                    }
                });

This code could be placed into the constructor of SampleData and then there is no need for an extra file "GroupedDropHandler". Hence, my suggested PR raises the convenience of creating instances of IDropTarget with not much or specific logic.

And yes, it is a wrapper around functionality. But it doesn't wrap a specific existing IDropTarget-implementation, but it lets the functionality be injected through lamdas (Funcs/Actions). Thus, it can be used in highly generic way.

If you don't think this PR fits into this library, it is absolutely okay. If this PR won't be accepted then I'll just implement these classes into my projects. Everyone else can easily do so as well. However, when I found the library LambdaConverters (which applies the same principle to IValueConverters) it was a simple yet game-changing thing to me. And only from that point on I started to see were I myself can apply this pattern. Like my past self I think that there are a lot of developers who don't know about such patterns at all or don't know where and when to apply. Until they stumble onto applied examples like myself. So I thought the IDragSource and IDropTarget would be a good fit for this pattern and hence I suggested this PR.

@punker76 punker76 changed the base branch from dev to develop August 15, 2020 11:03
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.

2 participants