如何使用"外观和感觉编码切割操作"像File Explorer

时间:2016-06-12 14:58:38

标签: vb.net listview

我需要使用相同的" Look&amp ;;感觉"我看到我是否在window explorer中执行相同的操作。

我在win XP和7上使用visual studio 2008 SP1(专业和快速)

我有一个带有两个listview的表单;每个列表视图都在列表视图中,每个列表视图控制一个文件夹并显示该文件夹的文件列表。每行包含带有自己图标的文件名。该图标从文件本身中提取并存储在ImageList控件中。

Folder display

剪切和粘贴操作正常,所以我的问题是" visual"部分。在窗口浏览器中,当选择的文件被剪切时(通过上下文菜单或CTRL-X),图标将变为禁用或无颜色状态。我希望执行相同的行为。我找到了以下代码:

ControlPaint.DrawImageDisabled(lvwDocFiles.CreateGraphics, _
                               imgFileIcons.Images(Item.ImageKey), _
                               Item.Position.X, Item.Position.Y, _
                               lvwDocFiles.BackColor)

此代码工作正常,图标将被禁用。

disabled icons

但是当我将listview粘贴到其他listview图标上时,视觉状态恢复正常。

那么,在操作完成之前,如何禁用图标?

我使用的代码是从mnuCut.Click或CTRL-X keypress调用的子代码

    With lvwDocFiles
    If .SelectedItems.Count > 0 Then
        ClipboardContent = Process.GetCurrentProcess.Id.ToString & STAR & _
                           (Convert.ToSByte(FilesCopy)).ToString & STAR & _
                           LinkType.ToString & STAR & _
                           FolderID.ToString & STAR & _
                           CodePlantArea.ToString & STAR & _
                           CodePlantUnit.ToString & STAR & _
                           CodedDocNumber & STAR & _
                           NumRev & STAR & _
                           CodeSender.ToString & STAR & _
                           FilesPath
        For Each Item As ListViewItem In .SelectedItems
            ClipboardContent = ClipboardContent & STAR & Item.Name & STAR & Item.Tag.ToString
            If Not FilesCopy Then
                'IconHeight = imgFileIcons.Images(Item.ImageKey).Height
                'IconWidth = imgFileIcons.Images(Item.ImageKey).Width
                ControlPaint.DrawImageDisabled(lvwDocFiles.CreateGraphics, _
                                               imgFileIcons.Images(Item.ImageKey), Item.Position.X, _
                                               Item.Position.Y, lvwDocFiles.BackColor)
            End If
            Item = Nothing
        Next Item
        Try
            Dim LinkFileObject As String = ClipboardContent
            Dim LinkFileDataObject As New DataObject(LinkFileFormat.Name, LinkFileObject)
            Clipboard.SetDataObject(LinkFileDataObject)
            LinkFileDataObject = Nothing
            LinkFileObject = Nothing
        Catch ex As Exception
            Cursor.Current = Cursors.Default
            MessageBox.Show(ex.Message, CutOrCopy & " Files", MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
        End Try
    End If
End With

1 个答案:

答案 0 :(得分:0)

我想说明我找到的解决方案。问题是,在CUT / PASTE操作期间,在视觉上获得与在文件资源管理器窗口中执行相同操作时相同的行为:显示在禁用模式下剪切的项目的图标。使用以下语句禁用图标:

ControlPaint.DrawImageDisabled(......)

我最初将此声明放在运行剪切操作的子节点中,但第一次重新设计列表视图时,禁用的图标会恢复正常显示。

按照@Plutonix评论我已经意识到必须手动执行listview的重新设计。所以当CUT的操作开始时,我做了两件事:

  1. 我将剪切的项目存储在CuttedItems集合中;这将在稍后重新设计listview时使用,因为所选项目可能不会更多
  2. 我使用ListView1.OwnerDraw = True
  3. 激活手动重新设计

    列表视图在视图LIST中,所以我只需要编写ListView1.DrawItem事件,您可以在下面看到:

    Private Sub lvwDocFiles_DrawItem(ByVal sender As Object, _
                 ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) _
            Handles lvwDocFiles.DrawItem
    '
    ' Identify sender
    '
        Dim lvw As ListView = DirectCast(sender, ListView)
    '
    ' Clears background
    '
        e.DrawBackground()
    '
    ' Identify item image
    '
        Dim itemImage As Image = e.Item.ImageList.Images(e.Item.ImageKey)
    '
    ' Draw item selected or unselected
    '
        If e.Item.Selected Then
            e.Graphics.FillRectangle( _
                     SystemBrushes.Highlight, _
                     New RectangleF(e.Bounds.X + itemImage.Width, _
                                    e.Bounds.Y, _
                                    e.Graphics.MeasureString(e.Item.Text, _
                                    lvw.Font, lvw.Width).Width, _
                                    e.Bounds.Height))
    
            e.Graphics.DrawString(e.Item.Text, lvw.Font, _
                                  SystemBrushes.HighlightText, _
                                  e.Bounds.X + itemImage.Width, _
                                  e.Bounds.Y + 2)
        Else
            e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds)
            e.Graphics.DrawString(e.Item.Text, lvw.Font, _
                                  SystemBrushes.WindowText, _
                                  e.Bounds.X + itemImage.Width, _
                                  e.Bounds.Y + 2)
        End If
    '
    ' Draw the image
    '
        If CuttedItems IsNot Nothing Then
            If CuttedItems.Contains(e.Item) Then
                ControlPaint.DrawImageDisabled(lvw.CreateGraphics, _
                                               itemImage, _
                                               e.Item.Position.X, _
                                               e.Item.Position.Y, _
                                               lvw.BackColor)
            Else
                e.Graphics.DrawImage(itemImage, _
                                     New PointF(e.Bounds.X, e.Bounds.Y))
            End If
        Else
            e.Graphics.DrawImage(itemImage, _
                                 New PointF(e.Bounds.X, e.Bounds.Y))
        End If
    
    End Sub
    

    如果CUT操作停止(例如按ESC键或启动其他操作,如COPY / PASTE),ListView1.OwnerDraw将设置为False,因此listview的重新设计将默认完成。

    最后一点。在重新设计项目的文本时,我在e.Bounds.Y中添加了2。这是尝试找到的值。这是因为将OwnerDraw从FALSE更改为TRUE(反之亦然)我注意到该项目的文本没有保持在同一个Y.我无法理解为什么所以我采用了这个"经验"溶液