Hi,
I'm trying to get the Drag/Drop framework to work well in my Application, but have some issue with data binding.
Basically, I'm using the drag/drop framework on a the DataTemplates of a ListBox and I want the behaviour and look of drag/drop to use data from the underlying View Model.
1. I want e,g, to enable Drag/Drop based on a property of my View Model (DataTemplate's DataContext):
<ig:DragSource IsDraggable="{Binding IsFileMarker}"/>
(IsFileMarker is a property of the View Model)
2. I want to use properties of my View Model (DataTemplate's DataContext) in the DragTemplate:
<ig:DragSource.DragTemplate>
<DataTemplate>
<Border>
<TextBlock Text="{Binding AnnotationItem.Name}" Margin="5" />
</Border>
</DataTemplate>
</ig:DragSource.DragTemplate>
(AnnotationItem is a property of the View Model)
None of these bindings work. Why ?
Regards,Leif Opseth
Hello Lief,
I am just checking if you require any further assistance on the matter.
Sincerely,
Krasimir, MCPD
Developer Support Supervisor - XAML
Infragistics
www.infragistics.com/support
Thank you for your feedback. Please let me know if you need any further assistance on the matter.
instantiating the View Model in the Resources section is not an option, since it violates the way we use the MVVM pattern.
I think I can add some extension code that utilizes your second approach, e.g. by wrapping such binding functionality in a dedicated DragSource subclass. I want to avoid putting the code in the code behind, as your provided sample shows. It looks promising so far.
Also, for the DragSource.DragTemplate part, I've found that I can actually bind directly to the parent DataTemplate's DataContext if I use the reference source binding option, e.g.:
<ig:DragSource.DragTemplate> <DataTemplate> <Border> <TextBlock Text="{Binding Source={x:Reference border}, Path=DataContext.AnnotationItem.Name}" /> </Border> </DataTemplate></ig:DragSource.DragTemplate>
This trick does not work for the IsDraggable binding however, as this creates a cyclical reference exception. I therefore have to use your workaround to get this binding to work.
Regards,Leif
Hello Leif,
Thank you for your post. I have been looking into your question and when you are using binding with no source defined, the source is the DataContenxt of the object, and since the DragSource does not derive from FrameworkElement class, it does not contains a DataContext property. In order to be able to apply the bindings, you can define your ViewModel in the Resources for your Window for example and to set the Source of the Bindings:
………….
<Window.Resources>
<local:MainVM x:Key="vm"/>
</Window.Resources>
…………….
<ig:DragDropManager.DragSource>
<ig:DragSource
IsDraggable="{Binding Source={StaticResource vm}, Path=IsFileMarker}"
DataObject="{Binding Source={StaticResource vm}}">
<TextBlock Text="{Binding Data.AnnotationItem.Name}" Margin="5" />
</ig:DragSource>
</ig:DragDropManager.DragSource>
Another approach that you can use is to bind the IsDraggable and the DataObject properties to the AssosiatedObject of the DragSource. To do that, you can handle the Loaded event of the element which will be your DragSource and you can set the bindings in the event handler:
private void drag_Loaded(object sender, RoutedEventArgs e)
{
DragSource source = DragDropManager.GetDragSource(sender as DependencyObject);
BindingOperations.SetBinding(source,
DragSource.IsDraggableProperty,
new Binding
RelativeSource = new RelativeSource(RelativeSourceMode.Self),
Path = new PropertyPath("AssociatedObject.DataContext.IsFileMarker"),
});
DragSource.DataObjectProperty,
Path = new PropertyPath("AssociatedObject.DataContext"),
}
I have created a sample application for you, that shows how you can implement this approach.
Please let me know if you need any further assistance on the matter.