Для примера на WPF.
После запуска программы в окне изображается две полосы прокрутки.
Разделим основной Grid на две строки, две колонки. По краям поместим ScrollBar, в большую часть Canvas.
В Canvas в качестве элементов, которые должны менять позицию, возьмем Button.
Также добавим обработчики события Button.Click и ScrollBar.Scroll.
<Window x:Class="Toster.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:local="clr-namespace:Toster"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800" MinWidth="200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="15"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="15"/>
</Grid.ColumnDefinitions>
<Canvas Name="Field">
<Button Canvas.Left="120" Canvas.Top="150"
Height="50" Width="50" Click="Button_Click"/>
<Button Canvas.Left="250" Canvas.Top="180"
Height="50" Width="50" Click="Button_Click"/>
</Canvas>
<ScrollBar x:Name="VerticalScrollBar"
HorizontalAlignment="Right"
Grid.Column="1" Grid.Row="0"
Scroll="VerticalScrollBar_Scroll"/>
<ScrollBar x:Name="HorizontalScrollBar"
Orientation="Horizontal" VerticalAlignment="Bottom"
Grid.Column="0" Grid.Row="1"
Scroll="HorizontalScrollBar_Scroll"/>
</Grid>
</Window>
В основном классе создадим два свойства:
1. Point SelectedPoint, в которой будут храниться координаты выбранного элемента
2. Button SelectedButton, которая будет хранить выбранный элемент.
ScrollBar сделаем неактивными, пока не будут выбраны объекты для перемещения.
Наводя указатель мыши на одну из двух фигур, можно выбирать, какая из этих фигур связана с полосами прокрутки.
В событии Button.Click ставим крестик выбранному Button. Сохраняем в свойства SelectedButton и SelectedPoint выбранный элемент и его координаты соответственно.
Значения свойства Value у ScrollBar заполняем относительным положение Button на Canvas.
При перемещении полосы прокрутки, создаем новую точку с обратно высчитанными координатами и присваиваем новое положение элемента на Canvas.
public partial class MainWindow : Window
{
public Point SelectedPoint { get; set; }
public Button SelectedButton { get; set; }
public MainWindow()
{
DataContext = this;
InitializeComponent();
VerticalScrollBar.IsEnabled = false;
HorizontalScrollBar.IsEnabled = false;
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (SelectedButton != null)
SelectedButton.Content = "";
SelectedButton = sender as Button;
SelectedButton.Content = "X";
SelectedPoint = SelectedButton.TransformToAncestor(Field).Transform(new Point(0, 0));
VerticalScrollBar.Value = SelectedPoint.Y / Field.ActualHeight;
HorizontalScrollBar.Value = SelectedPoint.X / Field.ActualWidth;
VerticalScrollBar.IsEnabled = true;
HorizontalScrollBar.IsEnabled = true;
}
private void VerticalScrollBar_Scroll(object sender, ScrollEventArgs e)
{
SelectedPoint = new Point(SelectedPoint.X, VerticalScrollBar.Value * Field.ActualHeight);
Canvas.SetTop(SelectedButton, SelectedPoint.Y);
}
private void HorizontalScrollBar_Scroll(object sender, ScrollEventArgs e)
{
SelectedPoint = new Point(HorizontalScrollBar.Value * Field.ActualWidth, SelectedPoint.Y);
Canvas.SetLeft(SelectedButton, SelectedPoint.X);
}
}
Пример простой, непрофессиональный, но рабочий. Остальное в ваших руках :)