WPF:将图像拖放到ListView

时间:2018-06-07 10:52:53

标签: c# wpf xaml drag-and-drop scrollview

我有两个列表视图,右侧列表视图绑定了数据。我实现了一个拖放操作,我可以将图像从左侧列表视图拖动到右侧列表视图。我无法将图像放在右侧列表视图中,因为它有数据绑定到它。所以我创建了一个透明的Canvas顶部来放置图像。

现在的问题是当我滚动右侧列表时,图像被固定到它最初放置的位置,但我希望它与listview项目一起滚动。下面我给出了我的.xaml和.cs代码。如果有人可以帮助我或者至少给我指示会很棒。

<Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="0.6*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>        
        <DockPanel Grid.Column="0">
            <ScrollViewer>
                <ListView Margin="10" x:Name="DragList" PreviewMouseLeftButtonDown="DragList_PreviewMouseLeftButtonDown" PreviewMouseMove="DragList_PreviewMouseMove">
                    <ListViewItem>
                        <StackPanel Orientation="Horizontal">
                            <Image Source="image.png" Margin="0,0,5,0" Height="96"/>                            
                        </StackPanel>
                    </ListViewItem>
                </ListView>
            </ScrollViewer>
        </DockPanel>

        <Grid Grid.Column="1" x:Name="droppingGrid">
        <ScrollViewer x:Name="xscroll"
        VerticalScrollBarVisibility="Auto"
        HorizontalScrollBarVisibility="Auto" Margin="0,0,0,0" ScrollChanged="xscroll_ScrollChanged">
            <StackPanel Orientation="Vertical">
                <ListView x:Name="TvBox" HorizontalAlignment="Right" DragEnter="TvBox_DragEnter" Drop="TvBox_Drop"
                       AllowDrop="True"   VerticalAlignment="Top" >
                    <ItemsControl.ItemsPanel>
                        <ItemsPanelTemplate>
                            <UniformGrid Rows="6" HorizontalAlignment="Stretch"/>
                        </ItemsPanelTemplate>
                    </ItemsControl.ItemsPanel>
                    <ListView.ItemTemplate>
                        <DataTemplate>
                            <Border BorderBrush="Gray" Background="Gray" BorderThickness="0, 0, 0, 4" DockPanel.Dock="Top">
                                <StackPanel Orientation="Vertical" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,4,1,4" >
                                    <Image Source="{Binding ImageData}" Width="400"
                                       VerticalAlignment="Top" Stretch="Uniform"/>
                                </StackPanel>
                            </Border>
                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </StackPanel>
        </ScrollViewer>        
        <StackPanel HorizontalAlignment="Left" Height="100" Margin="296,195,0,0" VerticalAlignment="Top" Width="100"/>
        </Grid>
    </Grid>

后端

List<string> _images = null;
        Point startPoint;

        public MainWindow()
        {
            InitializeComponent();

            List<string> imageList = new List<string>();

            string folder = "folderpath";
            string imgname = "test.jpg";

            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);

            this.TvBox.ItemsSource = new ImageDetails[]
            {
                new ImageDetails{ImageData=LoadImage(imageList[0])},
                new ImageDetails{ImageData=LoadImage(imageList[1])},
                new ImageDetails{ImageData=LoadImage(imageList[2])},
                new ImageDetails{ImageData=LoadImage(imageList[3])},
                new ImageDetails{ImageData=LoadImage(imageList[4])},
                new ImageDetails{ImageData=LoadImage(imageList[5])}
            };
        }

        private List<string> createList()
        {
            List<string> imageList = new List<string>();

            string folder = "folderpath";
            string imgname = "Poster.jpg";

            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname); 
            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);
            imageList.Add(folder + imgname);

            return imageList;
        }

        private BitmapImage LoadImage(string filename)
        {
            return new BitmapImage(new Uri(filename));
        }

        private void DragList_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            startPoint = e.GetPosition(null);
        }       

        private void DragList_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            Point mousePos = e.GetPosition(null);
            Vector diff = startPoint - mousePos;

            if (e.LeftButton == MouseButtonState.Pressed &&
                Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
                Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
            {

                ListView listView = sender as ListView;

                ListViewItem listViewItem =
                    FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

                if (listViewItem == null) return;

                ListViewItem contact = (ListViewItem)listView.ItemContainerGenerator.
                    ItemFromContainer(listViewItem);

                DataObject dragData = new DataObject("myFormat", contact);
                DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Move);
            }
        }

        private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject
        {
            do
            {
                if (current is T)
                {
                    return (T)current;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            while (current != null);
            return null;
        }

        private void TvBox_DragEnter(object sender, DragEventArgs e)
        {
            if (!e.Data.GetDataPresent("myFormat") || sender == e.Source)
            {
                e.Effects = DragDropEffects.Move;
            }
        }

        private void TvBox_Drop(object sender, DragEventArgs e)
        {
            Canvas dropCanvas = new Canvas();

            object el = e.Source;

            Point endpoint = e.GetPosition(xscroll);

            if (!droppingGrid.Children.Contains(dropCanvas))
            {

                if (e.Data.GetDataPresent("myFormat"))
                {
                    ListViewItem contact = e.Data.GetData("myFormat") as ListViewItem;

                    string childXaml = XamlWriter.Save(contact);
                    StringReader stringReader = new StringReader(childXaml);
                    XmlReader xmlReader = XmlReader.Create(stringReader);
                    UIElement clonedChild = (UIElement)XamlReader.Load(xmlReader);

                    double xaxis = endpoint.X;
                    double yaxis = endpoint.Y;
                    Canvas.SetTop(clonedChild, yaxis);
                    Canvas.SetLeft(clonedChild, xaxis);
                    dropCanvas.Children.Add(clonedChild);
                }

                droppingGrid.Children.Add(dropCanvas);
            }
        }

0 个答案:

没有答案