将项目从列表框拖放并启动方法,然后放入特定的画布

时间:2012-06-25 18:59:33

标签: c# wpf canvas drag-and-drop listbox

我对C#很陌生,所以请尽量保持简单。 我的问题如下:我有一个Listbox,我在运行时动态添加Items,我的UI中也有四个不同的画布。 现在,用户必须能够从列表框中拖动任何项目并将其放入四个画布中的一个。 在删除时,将启动一个方法,该方法需要知道哪个项目已被拖拽,以及放置哪个Canvas。

我还没有实现任何东西,但至少在这里我的XAML:

<Grid Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="gridMenu" VerticalAlignment="Stretch" Width="Auto" Background="#FFE6E6E6">
     <ListBox Grid.Row="2" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="listBox1" VerticalAlignment="Stretch" Width="Auto" Background="#FFE6E6E6" BorderBrush="{x:Null}" Panel.ZIndex="1" PreviewMouseDown="listBox1_PreviewMouseLeftButtonDown">
        <ListBoxItem Content="test1" />
        <ListBoxItem Content="test2" />
        <ListBoxItem Content="test3" />
        <ListBoxItem Content="test4" />
        <ListBoxItem Content="test5" />
    </ListBox>
</Grid>
<Grid Grid.Column="1" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="gridImage" VerticalAlignment="Stretch" Width="Auto" TextBlock.Drop="grid1_Drop">
    <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
        <Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage1" VerticalAlignment="Stretch" Width="Auto" />
        <Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage2" VerticalAlignment="Stretch" Width="Auto" Grid.Column="1" />
        <Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage3" VerticalAlignment="Stretch" Width="Auto" Grid.Row="1" />
        <Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage4" VerticalAlignment="Stretch" Width="Auto" Grid.Column="1" Grid.Row="1" />
</Grid>

2 个答案:

答案 0 :(得分:2)

本教程可以帮助您入门:http://wpftutorial.net/DragAndDrop.html

答案 1 :(得分:2)

我认为拖放不是一个简单的主题,所以我担心我不能那么简单,我同意ekholm:你肯定需要一个体面的c#/ wpf知识才能成功实现这个。即使您运行代码,当您想要修改/扩展DragDrop代码时,也会遇到困难。

以下是根据您提供的标记开始使用的示例:

<强> XAML:                                                                                                                      

    <Grid Grid.Row="1" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="gridImage" VerticalAlignment="Stretch" Width="Auto">
      <Grid.RowDefinitions>
        <RowDefinition />
        <RowDefinition />
      </Grid.RowDefinitions>
      <Grid.ColumnDefinitions>
        <ColumnDefinition />
        <ColumnDefinition />
      </Grid.ColumnDefinitions>

      <Canvas Background="LightGreen" AllowDrop="True" Drop="canvasImage_Drop" DragEnter="canvasImage_DragEnter" Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage1" VerticalAlignment="Stretch" Width="Auto" />

      <Canvas Background="LightYellow" AllowDrop="True" Drop="canvasImage_Drop" DragEnter="canvasImage_DragEnter"  Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage2" VerticalAlignment="Stretch" Width="Auto" Grid.Column="1" />

      <Canvas Background="LightPink" AllowDrop="True" Drop="canvasImage_Drop" DragEnter="canvasImage_DragEnter"  Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage3" VerticalAlignment="Stretch" Width="Auto" Grid.Row="1" />

      <Canvas Background="LightSteelBlue" AllowDrop="True" Drop="canvasImage_Drop" DragEnter="canvasImage_DragEnter"  Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage4" VerticalAlignment="Stretch" Width="Auto" Grid.Column="1" Grid.Row="1" />
    </Grid>
  </Grid>

代码背后:

private Point _startPoint;
private static readonly string _dropIdentifier = "dropIdentifier";

private void listBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
  // The initial mouse position
  _startPoint = e.GetPosition(null);
}

private void listBox_PreviewMouseMove(object sender, MouseEventArgs e)
{
  // Get the current mouse position
  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))
  {
    // Get the dragged ListBoxItem
    var listBox = sender as ListBox;
    var listBoxItem = listBox.SelectedItem;

    // Initialize the drag & drop operation
    DataObject dragData = new DataObject(_dropIdentifier, listBoxItem);
    DragDrop.DoDragDrop(listBox, dragData, DragDropEffects.Move);
  } 
}

private void canvasImage_Drop(object sender, DragEventArgs e)
{
  if (e.Data.GetDataPresent(_dropIdentifier))
  {
    var item = e.Data.GetData(_dropIdentifier) as ListBoxItem;
    DropOnCanvas(sender as Canvas, item);
  }
}

private void canvasImage_DragEnter(object sender, DragEventArgs e)
{
  if (!e.Data.GetDataPresent(_dropIdentifier) ||
    sender == e.Source)
  {
    e.Effects = DragDropEffects.None;
  }
}

public void DropOnCanvas(Canvas targetCanvas, ListBoxItem item)
{
  // do your stuff here ...
  int textHeight = 20;
  var text = new TextBlock() { Text = item.Content.ToString(), Height = textHeight };
  Canvas.SetTop(text, targetCanvas.Children.Count * textHeight);
  targetCanvas.Children.Add(text);
}