VB.NET-自定义Listview/Listbox
所以有几个问题得到了回答,但我还是不明白我该做什么。比如我怎样才能基本上使我的Listview非常定制 我想让它看起来像是: 正如你所看到的,它是高度定制的——如果你想知道的话,我是在Photoshop中制作的,我现在不需要定制滚动条或悬停高亮效果,但将来需要一种方法来实现 有什么办法可以做到这一点吗 编辑:我能找到的最接近的东西是: 但是有一些“问题”-我无法使文本对齐/位置看起来正确,因为我需要在文本前留出两个空格,使其看起来真实得体,这“可能”会在将来尝试单击时给我带来问题。接下来,由于某些原因,没有使用边框/网格的选项,这会消除在第一幅图像中框周围使用稍微暗一点的灰色边框的能力。有什么想法吗,伙计们 (我以前是这样做的:) 编辑2:重新编辑:好的,我想我已经对高光颜色进行了排序,但它看起来不像我使用的FillRectangle,但无论我如何设置边界(这是正确的),在刷新和消失之前,它似乎会留下额外的1px白色边界约1-2秒。怎么解决这个问题 编辑3:我“几乎”完成的列表框对我来说不起作用,因为它不稳定-如果我在设计模式下编辑ColorListBox后编辑任何内容,它将不起作用,并给我错误,这很烦人。它也有“SelectedItem”参数,因为它不再是破坏我一半代码的对象。另外,如果这两个是可修复的,我想它会工作,但我不知道如何修复它:(VB.NET-自定义Listview/Listbox,.net,vb.net,listbox,.net,Vb.net,Listbox,所以有几个问题得到了回答,但我还是不明白我该做什么。比如我怎样才能基本上使我的Listview非常定制 我想让它看起来像是: 正如你所看到的,它是高度定制的——如果你想知道的话,我是在Photoshop中制作的,我现在不需要定制滚动条或悬停高亮效果,但将来需要一种方法来实现 有什么办法可以做到这一点吗 编辑:我能找到的最接近的东西是: 但是有一些“问题”-我无法使文本对齐/位置看起来正确,因为我需要在文本前留出两个空格,使其看起来真实得体,这“可能”会在将来尝试单击时给我带来问题。接下来,由于
因此,我现在恢复到一个非常基本的列表框,只包含文本,直到你们能够找到一种方法来定制它,就像上面的第一张图片一样。根本不清楚你们到底想要什么。
比如我如何基本上使我的列表视图非常定制。
是模糊的,非常广泛的(以及为什么你们没有得到一个你们喜欢的答案)
图片很好,但描述所需外观的文字会更好。如果要仔细查看图片,就无法知道什么是重要的,什么是重要的……因为。我假设每个细节都是基于非常定制的而重要的。此外:
Listview/Listbox
选择一个:它们是非常不同的控件
- 对于
列表视图
,项目之间的小2像素边距将非常有问题,因此我划伤了LV1
- 为什么第一幅图像中的所有项目都是灰色的?这通常表示已禁用,因此可以禁用项目(例如,当给定频道没有节目数据时)
- “FOX”上的灰色框代表什么?它是所选项目吗?它是HotLight/MouseHover项目吗?
ListBox
/ListView
项目通常不会在鼠标经过时亮起(当HotTracking
为真时,LV可以亮起,但只有当鼠标位于项目
而不是子项目上时才亮起)
- 框矩形的深灰色是绝对颜色吗?
HotLight
和Selected
的颜色通常由操作系统(=操作系统)根据用户的主题和颜色选择来处理。这个小工具应该忽略这些吗,还是您的主题使用一些灰色作为突出显示
我仔细测量了第一张图片中的元素,以获得一些指标,然后对上面的答案进行了猜测
无代码解决方案
使用按钮。由于用户可能会单击其中一个按钮来选择所需频道,按钮
比列表视图
更有意义(更多)。您可以在按钮上显示图像和文本,并使用FlatAppearance
属性设置所需样式。使用标记可以跟踪频道ID或集合中相关频道的索引
最后,使用MouseHover
和MouseLeave
事件操纵FlatAppearance.BorderSize
和FlatAppearance.BorderColor
以非常接近问题中的第一幅图像:
它们位于滚动的面板中。面板宽度比控件略宽,以避免水平滚动条。至于按钮,热灯边框(?)它围绕着整个控件,而不仅仅是文本。这不是您的图片所显示的内容,但另一方面,除了一些标准属性和一些事件处理代码(5-6行)之外,它不涉及任何内容
图像列表框
ownerdraw列表框将使您更接近所需内容,但最终这只会使它看起来像一个带有按钮的列表框
在表单上放置一个列表框,并设置以下属性:
-DrawMode=OwnerDrawFixed
-积分高度=假
-Itemheight=64(这是基于第一个图像中的图像为60x60这一事实)
-将背景色设置为ControlLight
或{233233}
,以获得所需的确切灰度
如前所述,ListBox
项目在鼠标悬停时通常不会亮起,因此我们需要一些代码来跟踪它们(如按钮
):
绘制代码需要实现该接口,以便它可以使用这些属性绘制项目。Id
是一个额外的接口,用于链接从集合中选择或单击的列表框
项目(仅当您将项目添加到列表框
时才需要此接口,不推荐使用)。如果需要,可以将其扩展为包含一个启用的
属性,以便以不同的方式绘制这些属性。您可以在collection items类上实现此接口
Private mouseItem As Int32 = -1
Private Sub lbChannels_MouseMove(sender As Object,
e As MouseEventArgs) Handles lbChannels.MouseMove
Dim ndx = lbChannels.IndexFromPoint(e.Location)
' test to avoid millions of paints
If ndx <> mouseItem Then
If mouseItem <> -1 Then
' invalidate/redraw the OLD itemrect
lbChannels.Invalidate(lbChannels.GetItemRectangle(mouseItem))
End If
mouseItem = ndx
' invalidate/redraw the NEW itemrect
lbChannels.Invalidate(lbChannels.GetItemRectangle(mouseItem))
End If
End Sub
Private Sub lbChannels_MouseLeave(sender As Object,
e As EventArgs) Handles lbChannels.MouseLeave
If mouseItem <> -1 Then
' get rect for what wont be the hot item in a tick
Dim rect = lbChannels.GetItemRectangle(mouseItem)
'lbChannels.Invalidate()
mouseItem = -1 ' no longer Hot
lbChannels.Invalidate(rect)
End If
End Sub
Public Interface IImageItem
Property ID As String ' ???
Property ItemImage As Image
Property Text As String
End Interface
Public Class ChannelItem
Implements IImageItem
Public Property ItemImage As Image Implements IImageItem.ItemImage
Public Property Text As String Implements IImageItem.Text
Public Property ID As String Implements IImageItem.ID
' + your existing properties
Public Sub New(txt As String, img As Image, key As String)
Text = txt
ItemImage = img
ID = key
End Sub
Public Overrides Function ToString() As String
Return Text
End Function
End Class
Private Sub lbChannels_DrawItem(sender As Object,
e As DrawItemEventArgs) Handles lbChannels.DrawItem
Dim lb As ListBox = lbChannels
If e.Index < 0 Then
TextRenderer.DrawText(e.Graphics, "", lb.Font, e.Bounds, lb.ForeColor)
Return
End If
Dim iItem As IImageItem
If TypeOf (lb.Items(e.Index)) Is IImageItem Then
iItem = DirectCast(lb.Items(e.Index), IImageItem)
Else
TextRenderer.DrawText(e.Graphics, lb.Items(e.Index).ToString,
lb.Font, e.Bounds, lb.ForeColor)
Return
End If
Dim imgRect As Rectangle = Rectangle.Empty
Dim txtRect As Rectangle
' calc
If iItem.ItemImage IsNot Nothing Then
imgRect = New Rectangle(e.Bounds.X + 1, e.Bounds.Y + 1,
iItem.ItemImage.Width + 2, iItem.ItemImage.Height + 2)
End If
' GetTextExtent
Dim sz = TextRenderer.MeasureText(" " & iItem.Text, lb.Font)
txtRect = New Rectangle(iItem.ItemImage.Width + 4, e.Bounds.Y + 1,
(e.Bounds.Width - iItem.ItemImage.Width) - 8,
e.Bounds.Height - 2)
' Draw Big Box around the text portion
If e.Index = mouseItem Then
Using pR As New Pen(SystemColors.ControlDark, 2),
brB As New SolidBrush(SystemColors.Window)
e.Graphics.DrawRectangle(pR, txtRect)
txtRect.Inflate(-1, -1)
e.Graphics.FillRectangle(brB, txtRect)
End Using
ElseIf (e.State.HasFlag(DrawItemState.Selected)) Then
' ToDo: modify for whatever is desired for the selected item
' this is a guess/example
Using pR As New Pen(SystemColors.Highlight, 2),
brB As New SolidBrush(SystemColors.Window)
e.Graphics.DrawRectangle(pR, txtRect)
txtRect.Inflate(-1, -1)
e.Graphics.FillRectangle(brB, txtRect)
End Using
Else
' could use a channel specific color for each BG
' just extend IImageItem
e.DrawBackground()
End If
If iItem.ItemImage IsNot Nothing Then
e.Graphics.DrawImage(iItem.ItemImage, imgRect)
End If
' recalc TR for where the text really goes
txtRect = New Rectangle(iItem.ItemImage.Width + 4, e.Bounds.Y + 1,
sz.Width + 2, e.Bounds.Height - 0)
TextRenderer.DrawText(e.Graphics, iItem.Text, lb.Font, txtRect, lb.ForeColor)
End Sub
' a collection of ChannelItem objects (which implement IImageItem)
Dim channels As New List(Of ChannelItem)
' my fake data
channels.Add(New ChannelItem("More 4", My.Resources.SO_LVImg01, "M4"))
channels.Add(New ChannelItem("Channel 4", My.Resources.SO_LVImg02, "4"))
channels.Add(New ChannelItem("RTE One", My.Resources.SO_LVImg03, "RET1"))
channels.Add(New ChannelItem("FOX", My.Resources.SO_LVImg04, "Fox"))
...
lbChannels.DataSource = channels