Я хочу включить перетаскивание в моем приложении, чтобы иметь возможность создавать соединения между компонентами. Это звучит не слишком сложно, но проблема в типе компонентов, между которыми я хочу установить связь.
Причина, по которой я хочу иметь возможность устанавливать соединения, состоит в том, чтобы иметь возможность составлять график и вычислять кратчайший путь и т. Д.
У меня есть ListBox с компонентами, которые размещены на холсте. Причина, по которой я использую ListBox, состоит в том, чтобы сделать компоненты выбираемыми. Я также сделал их перетаскиваемыми.
<DataTemplate DataType="{x:Type ViewModels:DocumentViewModel}">
<DataTemplate.Resources>
<Converters:GuiSizeConverter x:Key="SizeConverter"/>
</DataTemplate.Resources>
<ListBox ItemsSource="{Binding Components}" SelectedItem="{Binding SelectedItem}" Background="Transparent"
HorizontalAlignment="Left" VerticalAlignment="Top" BorderThickness="0" Margin="0">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas ClipToBounds="True" Height="{Binding CurrentProject.Height, Converter={StaticResource SizeConverter}}"
Width="{Binding CurrentProject.Width, Converter={StaticResource SizeConverter}}">
<Canvas.Background>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.WindowFrameColorKey}}"/>
</Canvas.Background>
</Canvas>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border Background="{TemplateBinding Background}" />
<ContentPresenter/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#8868D5FD" />
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#4468D5FD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Utils:DraggableExtender.CanDrag" Value="True" />
<Setter Property="Canvas.Top" Value="{Binding Path=Y, Converter={StaticResource SizeConverter},Mode=TwoWay}" />
<Setter Property="Canvas.Left" Value="{Binding Path=X, Converter={StaticResource SizeConverter},Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
</DataTemplate>
Теперь хитроумно то, что я хочу использовать перетаскивание не компонентов в моей ViewModel, а компонентов внутри этих компонентов. Чтобы лучше это проиллюстрировать, см. Пример изображения железнодорожного вокзала и путей ниже. У меня есть PlaceableComponents (которые находятся в списке), то есть трек и станция. Трек состоит из TrackSections, которые могут быть обычными секциями треков и электрифицированными секциями треков). Станция состоит из платформ, которая состоит из треков, которые построены из TrackSections.
Таким образом, компоненты (или узлы), которые я хочу подключить, являются TrackSections, поэтому я хочу перетащить (используя правую кнопку мыши) раздел в другой раздел, и это должно вызвать метод (команду) в моем DocumentViewModel ( viewmodel, которая содержит элементы на холсте), а не в разделах, так как разделы не имеют никакого представления о других компонентах и не должны содержать соединение.
Цель состоит в том, чтобы создать список соединений (содержащих компоненты от и до), которые должны отображаться поверх всего в виде линий, используя слой украшений или аналогичный). Могу также добавить, что все компоненты, которые можно использовать для создания соединений, реализуют интерфейс INode, чтобы иметь возможность их идентифицировать.
Надеюсь, я достаточно четко изложил свой вопрос и ситуацию. Могу добавить, что я нашел много хороших сообщений о перетаскивании, но я не смог применить ни один из них к своему делу, поэтому я и спрашиваю здесь.