It is necessary to place through Binding a collection of pictures on Canvas, and so that each picture can be moved with the mouse.
View (XAML)
<Grid Background="DarkViolet"> <Grid.RowDefinitions> <RowDefinition Height="*" /> </Grid.RowDefinitions> <ItemsControl x:Name="Ccc" Grid.Row="0" ItemsSource="{Binding Path=Images}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas x:Name="fff" Width="800" Height="600" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Chartreuse"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Thumb Canvas.Left= "10" Canvas.Top="10" DragDelta="Thumb_DragDelta"> <Thumb.Template> <ControlTemplate> <Image Width="80" Height="80" Source="{Binding}" Stretch="UniformToFill" /> </ControlTemplate> </Thumb.Template> </Thumb> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </Grid> CodeBehind - an event for moving a picture inside a Canvas (catel framework is applied, but properties may be normal)
private void Thumb_DragDelta(object sender, DragDeltaEventArgs e) { var thumb = e.Source as FrameworkElement; var horizontalChange = Canvas.GetLeft(thumb) + e.HorizontalChange; var verticalChange = Canvas.GetTop(thumb) + e.VerticalChange; var maxHorizontalPoint = Ccc.ActualWidth - thumb.ActualWidth; var maxVerticalPoint = Ccc.ActualHeight - thumb.ActualHeight; if (horizontalChange < 0) { Canvas.SetLeft(thumb, 0); } else if (horizontalChange > maxHorizontalPoint) { Canvas.SetLeft(thumb, maxHorizontalPoint); } else { Canvas.SetLeft(thumb, horizontalChange); } if (verticalChange < 0) { Canvas.SetTop(thumb, 0); } else if (verticalChange > maxVerticalPoint) { Canvas.SetTop(thumb, maxVerticalPoint); } else { Canvas.SetTop(thumb, verticalChange); } } ViewModel - contains the BitmapImage collection
public class MainWindowViewModel : ViewModelBase { public MainWindowViewModel() { var circleUri = new Uri(String.Format(@"F:\Pictures\circle.png")); var rectangleUri = new Uri(String.Format(@"F:\Pictures\rectangle.png")); Image = new BitmapImage(circleUri); Images = new ObservableCollection<BitmapImage> { new BitmapImage(circleUri), new BitmapImage(rectangleUri) }; } public BitmapImage Image { get { return GetValue<BitmapImage>(ImageProperty); } set { SetValue(ImageProperty, value); } } public static readonly PropertyData ImageProperty = RegisterProperty("Image", typeof(BitmapImage)); public ObservableCollection<BitmapImage> Images { get { return GetValue<ObservableCollection<BitmapImage>>(ImagesProperty); } set { SetValue(ImagesProperty, value); } } public static readonly PropertyData ImagesProperty = RegisterProperty("Images", typeof(ObservableCollection<BitmapImage>)); } Pictures are added to the Canvas but do not mix, because Thumb does not see attached properties from Canvas. Canvas.Left and Canvas.Top. and any movements relative to the Canvas do not work accordingly.
<Thumb Canvas.Left= "10" Canvas.Top="10"/> A single object in the Canvas correctly handles the move.
<Canvas x:Name="Ccc" Grid.Row="0" Width="800" Height="600" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Chartreuse"> <Thumb Canvas.Left="10" Canvas.Top="10" Canvas.ZIndex="99" DragDelta="Thumb_DragDelta"> <Thumb.Template> <ControlTemplate> <Image Width="80" Height="80" Source="{Binding Path=Image}" Stretch="UniformToFill" /> </ControlTemplate> </Thumb.Template> </Thumb> </Canvas> Update
Replaced by
<ItemsControl x:Name="Ccc" Grid.Row="0" ItemsSource="{Binding Path=Images}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <Canvas Width="800" Height="600" Margin="15" HorizontalAlignment="Left" VerticalAlignment="Top" Background="Chartreuse"/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemContainerStyle> <Style TargetType="ContentPresenter"> <Setter Property="Canvas.Left" Value="10"/> <Setter Property="Canvas.Top" Value="10"/> <Setter Property="ContentTemplate"> <Setter.Value> <DataTemplate> <Thumb DragDelta="Thumb_DragDelta" > <Thumb.Template> <ControlTemplate> <Image Width="80" Height="80" Source="{Binding}" Stretch="UniformToFill" /> </ControlTemplate> </Thumb.Template> </Thumb> </DataTemplate> </Setter.Value> </Setter> </Style> </ItemsControl.ItemContainerStyle> </ItemsControl> But also did not help.
Canvas' it’s notItemthat is located directly, butItemContainer, and you need to set coordinates not inItemTemplate, but inItemContainerTemplate. It may be easier to abandonItemsControl, self-subscribe to theObservableCollectionchange, and putThumbin the code-behind directly onCanvas. - VladDItemContainerTemplate. Undoubtedly, the addition to the code-behind is not so elegant, so if it can be avoided, it is worth it. - VladDItemContainerTemplate- by what it is packed. For example, the blue background color of an element with a focus is done using the ItemContainer. - VladD