0

我正在尝试实现一个包含我的程序的“打开文件”的动态列表框。这些文件可以从 ListBox 拖到四个画布之一。只要在启动程序之前将项目添加到 XAML 中,就可以正常工作,但是,一旦我通过 fileList.Items.Add("myitemname"); 将项目添加到 ListBox; 如果我尝试将它们拖放(拖动)到 Canvas 中,我会得到一个 NullReferenceException

DragDrop.DoDragDrop(listBox, dragData, DragDropEffects.Move);

这是我的代码的相关部分:

public partial class MainWindow : Window
{
    InitialDataObject _initData = new InitialDataObject();

    public MainWindow()
    {
        InitializeComponent();
    }


    #region DragImage

    private void DragImageStart(object sender, MouseButtonEventArgs e)
    {
        _initData._mousePoint = e.GetPosition(null);
    }

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

        if (e.LeftButton == MouseButtonState.Pressed && (
        Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
        Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) && ((sender as ListBox).SelectedItem != null))
        {
            var listBox = sender as ListBox;
            var listBoxItem = listBox.SelectedItem;
            DataObject dragData = new DataObject(_initData._dropIdentifier, listBoxItem);
            DragDrop.DoDragDrop(listBox, dragData, DragDropEffects.Move); 
        }

    }

    private void CanvasDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(_initData._dropIdentifier))
        {
            var item = e.Data.GetData(_initData._dropIdentifier) as ListBoxItem;
            (sender as Canvas).Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
            DropImage(sender as Canvas, item);
            fileList.UnselectAll();
        }
    }

    private void CanvasDragEnter(object sender, DragEventArgs e)
    {
        if (!e.Data.GetDataPresent(_initData._dropIdentifier) || sender == e.Source)
        {
            (sender as Canvas).Background = new SolidColorBrush(Color.FromArgb(255, 240, 240, 240));
            e.Effects = DragDropEffects.None;
        } 
    }

    private void DropImage(Canvas targetCanvas, ListBoxItem item)
    {
        //just to check if I got the right item in this method
        MessageBox.Show(item.Content.ToString());
    }

    private void CanvasDragLeave(object sender, DragEventArgs e)
    {
        if (!e.Data.GetDataPresent(_initData._dropIdentifier) || sender == e.Source)
        {
            (sender as Canvas).Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
        }
    }

    #endregion

    private void sdfsdf(object sender, RoutedEventArgs e)
    {
        fileList.Items.Add("test");
    }
}

class InitialDataObject
{
    public Point _mousePoint = new Point();
    public readonly string _dropIdentifier = "dropIdentifier";
}

XAML:

<Grid Height="Auto" HorizontalAlignment="Stretch" Margin="0,23,0,0" Name="gridSubmain" VerticalAlignment="Stretch" Width="Auto" Panel.ZIndex="2">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="250" MaxWidth="250" MinWidth="250" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <ListBox Height="Auto" Name="fileList" Width="Auto" Background="#FFE6E6E6" BorderBrush="{x:Null}" Panel.ZIndex="1" PreviewMouseLeftButtonDown="DragImageStart" PreviewMouseMove="DragImageMove" FontSize="16" ItemsSource="{Binding}" Margin="0" Grid.Row="2">
        <ListBoxItem Content="dfgdfg" />
        <ListBoxItem Content="sfsdf" />
        <ListBoxItem Content="ghjgh" />
        <ListBoxItem Content="cvbcvb" />
    </ListBox>
    <Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="112,196,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="sdfsdf" />
</Grid>
<Grid Grid.Column="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 Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage1" VerticalAlignment="Stretch" Width="Auto" AllowDrop="True" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Background="White" DragLeave="CanvasDragLeave" />
    <Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage2" VerticalAlignment="Stretch" Width="Auto" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Grid.Column="1" AllowDrop="True" Background="White" DragLeave="CanvasDragLeave"/>
    <Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage3" VerticalAlignment="Stretch" Width="Auto" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Grid.Row="1" AllowDrop="True" Background="White" DragLeave="CanvasDragLeave"/>
    <Canvas Height="Auto" HorizontalAlignment="Stretch" Margin="0" Name="canvasImage4" VerticalAlignment="Stretch" Width="Auto" Drop="CanvasDrop" DragEnter="CanvasDragEnter" Grid.Column="1" Grid.Row="1" AllowDrop="True" Background="White" DragLeave="CanvasDragLeave"/>
</Grid>

任何想法为什么它使用现有项目而不是通过 fileList.Items.Add(".."); 添加的项目?此外,对于现有项目 fileList.UnselectAll(); 工作正常,但额外添加的项目保持选中状态,我无法摆脱选择。

4

1 回答 1

1

你的CanvasDrop方法有问题。您期望 ListBoxItem 在那里,但获取字符串,因为SelectedItem列表框的属性对于您在 xaml 中创建的项目和您动态添加的项目具有不同的值。

于 2012-06-27T15:38:49.593 回答