C # WPF Drag & Drop ListBox MVVM - PullRequest
       31

C # WPF Drag & Drop ListBox MVVM

2 голосов
/ 12 апреля 2011

Я хочу включить перетаскивание в моем приложении, чтобы иметь возможность создавать соединения между компонентами. Это звучит не слишком сложно, но проблема в типе компонентов, между которыми я хочу установить связь.

Причина, по которой я хочу иметь возможность устанавливать соединения, состоит в том, чтобы иметь возможность составлять график и вычислять кратчайший путь и т. Д.

У меня есть 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.

canvas in action

Таким образом, компоненты (или узлы), которые я хочу подключить, являются TrackSections, поэтому я хочу перетащить (используя правую кнопку мыши) раздел в другой раздел, и это должно вызвать метод (команду) в моем DocumentViewModel ( viewmodel, которая содержит элементы на холсте), а не в разделах, так как разделы не имеют никакого представления о других компонентах и ​​не должны содержать соединение.

Цель состоит в том, чтобы создать список соединений (содержащих компоненты от и до), которые должны отображаться поверх всего в виде линий, используя слой украшений или аналогичный). Могу также добавить, что все компоненты, которые можно использовать для создания соединений, реализуют интерфейс INode, чтобы иметь возможность их идентифицировать.

Надеюсь, я достаточно четко изложил свой вопрос и ситуацию. Могу добавить, что я нашел много хороших сообщений о перетаскивании, но я не смог применить ни один из них к своему делу, поэтому я и спрашиваю здесь.

1 Ответ

0 голосов
/ 29 июля 2011

Правильно ли, что вы хотите сначала разместить компоненты на холсте, а затем создавать связи между ними, перетаскивая их из одного компонента в другой? В чем сейчас ваша проблема с перетаскиванием? Почему вы думаете, тип компонентов является проблемой?

Я просто могу догадаться, чего вы действительно хотите, но, возможно, сработает следующий подход:

  • При щелчке правой кнопкой мыши определите компонент и сечение, по которому движется ваша мышь
  • При перетаскивании определить, если вы наводите другой компонент, который позволяет отбрасывать (дать визуальную подсказку)
  • Если опускание разрешено, проверьте участок пути, который вы зависаете
  • Создать соединение трексе

Вот ссылка на Drag & Drop-Framework .

...