S
S
sofronov2020-04-24 13:39:30
WPF
sofronov, 2020-04-24 13:39:30

What is the difference in Binding between Control and Template (using GongSolutions.Wpf.DragDrop as an example)?

I understand the MVVM device, I want to attach Drag`n`Drop to a window with controls attached to the viewmodel. In the window I create like the same ListBox, one directly, several according to the template from the list:

<Window x:Class="WpfDragDropTestApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:dd="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop"
        xmlns:local="clr-namespace:WpfDragDropTestApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.DataContext>
        <local:SimpleViewModel/>
    </Window.DataContext>

    <Window.Resources>
        <DataTemplate x:Key="MyItemTemplate"  DataType="{x:Type local:ItemVisualisation}">
            <Grid>
                <Ellipse Stroke="Black"
                             StrokeThickness="1"
                             Height="{Binding VisualDiameter}"
                             Width="{Binding VisualDiameter}"
                             >
                </Ellipse>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="MyControlDataTemplate" DataType="{x:Type local:MyListVisualisation}">
            <ListBox Margin="0"
        Width="{Binding VisualWidth}"
        Height="{Binding  VisualHeight}"
                        	dd:DragDrop.IsDragSource="True"
        dd:DragDrop.IsDropTarget="True"
                        	dd:DragDrop.DropHandler="{Binding}"
                        	dd:DragDrop.DragAdornerTemplate="{StaticResource MyItemTemplate}"
        ItemTemplate="{StaticResource MyItemTemplate}" 
                        >
            </ListBox>
        </DataTemplate>

    </Window.Resources>

    <StackPanel >
        <ListBox ItemTemplate="{StaticResource MyControlDataTemplate}"
                        ItemsSource="{Binding ListsCollection}"
            >
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"></StackPanel>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ListBox>
        <ListBox Margin="0"
                 Height="100"
                 ItemsSource="{Binding ItemsCollection}"
                 dd:DragDrop.IsDragSource="True"
                 dd:DragDrop.IsDropTarget="True"
                 dd:DragDrop.DropHandler="{Binding}"
                 dd:DragDrop.DragAdornerTemplate="{StaticResource MyItemTemplate}"
                 ItemTemplate="{StaticResource MyItemTemplate}" 
                >
        </ListBox>
    </StackPanel>
</Window>


The model is bound directly to the window.
using GongSolutions.Wpf.DragDrop;
using System.Collections.ObjectModel;

namespace WpfDragDropTestApp
{
    public class SimpleViewModel : DefaultDropHandler
    {
        public ObservableCollection<MyListVisualisation> ListsCollection { get; private set; }
        public ObservableCollection<ItemVisualisation> ItemsCollection { get; private set; }

        public override void Drop(IDropInfo dropInfo)
        {
            base.Drop(dropInfo);
        }

        public SimpleViewModel()
        {
            ListsCollection = new ObservableCollection<MyListVisualisation>();
            ListsCollection.Add(new MyListVisualisation() { VisualHeight = 200, VisualWidth = 400 });
            ListsCollection.Add(new MyListVisualisation() { VisualHeight = 250, VisualWidth = 250 });

            ItemsCollection = new ObservableCollection<ItemVisualisation>();
            ItemsCollection.Add(new ItemVisualisation() { VisualDiameter = 20 });
            ItemsCollection.Add(new ItemVisualisation() { VisualDiameter = 30 });
            ItemsCollection.Add(new ItemVisualisation() { VisualDiameter = 20 });
            ItemsCollection.Add(new ItemVisualisation() { VisualDiameter = 10 });
        }
    }
}

The drag and drop works just fine. Elements are dragged both inside each control and between any controls.
The issue is that the inherited Drop handler is only called when "dropping" inside an explicitly declared control, but not when dropping inside "template" ones.
Actually I really want to understand why and how to fix it?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
S
sofronov, 2020-04-29
@sofronov

He asked, he answered.
It's all about the DataContext. At the controls created on a template he looked in other place. I had to specify it manually (by running a search by type) and it all worked.

dd:DragDrop.DropHandler="{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question