I need to specify Canvas as a panel for elements and connect the ability to move elements in it.

There is such a markup.

<ItemsControl ItemsSource="{Binding MapObjects}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas IsItemsHost="True"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <ContentControl Content="{Binding}"> <i:Interaction.Behaviors> <behaviors:DragBehavior/> </i:Interaction.Behaviors> </ContentControl> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemContainerStyle> <Style TargetType="ContentPresenter"> <Setter Property="Canvas.Left" Value="{Binding Position.X}"/> <Setter Property="Canvas.Top" Value="{Binding Position.Y}"/> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl> 

From the markup it can be seen that in order to be bound to the Canvas.Top/Left attachment properties, Canvas.Top/Left necessary to do a binding through the ContentPresenter style, because each element is wrapped in a ContentPresenter . But I can’t specify Behaviors through styles, because the designer swears by such a foul language

The Behaviors property is not a DependencyProperty

I tried to do so

 <Setter Property="i:Interaction.Behaviors"> <Setter.Value> <behaviors:DragBehavior/> </Setter.Value> </Setter> 

And in the form in which it is now, it does not work, because the AssociatedObject in the DragBehavior code is ContentControl . Of course, I can find the element I need from the visual tree, but something tells me that there is a more elegant way that will not be so rigidly tied to the markup

    1 answer 1

    Found a solution here https://stackoverflow.com/a/4779168/5938996

    That's what happened

     <ItemsControl ItemsSource="{Binding MapObjects}"> <ItemsControl.Resources> <local:MyBehaviors x:Key="myBehaviors" x:Shared="False"> <behaviors:DragBehavior/> </local:MyBehaviors> </ItemsControl.Resources> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas IsItemsHost="True"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <ContentControl Content="{Binding}"> </ContentControl> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.ItemContainerStyle> <Style TargetType="ContentPresenter"> <Setter Property="Canvas.Left" Value="{Binding X, Mode=TwoWay}"/> <Setter Property="Canvas.Top" Value="{Binding Y, Mode=TwoWay}"/> <Setter Property="local:SupplementaryInteraction.Behaviors" Value="{StaticResource myBehaviors}"/> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl> 

    And code

     public class MyBehaviors : List<Behavior> { } public static class SupplementaryInteraction { public static MyBehaviors GetBehaviors(DependencyObject obj) { return (MyBehaviors)obj.GetValue(BehaviorsProperty); } public static void SetBehaviors(DependencyObject obj, MyBehaviors value) { obj.SetValue(BehaviorsProperty, value); } public static readonly DependencyProperty BehaviorsProperty = DependencyProperty.RegisterAttached("Behaviors", typeof(MyBehaviors), typeof(SupplementaryInteraction), new UIPropertyMetadata(null, OnPropertyBehaviorsChanged)); private static void OnPropertyBehaviorsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var behaviors = Interaction.GetBehaviors(d); foreach (var behavior in e.NewValue as MyBehaviors) behaviors.Add(behavior); } } 

    In short, Behaviors not a DependencyProperty . Fix it artificially.