- 題名: ListViewのハイライトの色設定
- 日時: 2010/01/15 22:12:33
- ID: 26259
- この記事の返信元:
- (なし)
- この記事への返信:
- [26261] Re[1]: ListViewのハイライトの色設定2010/01/16 2:02:51
- ツリーを表示
> ListViewの選択され、ハイライトになっている行の
> 背景色と文字色を変更したいです。
> (複数行の選択はNGとしています。)
> DataGridViewでいう
> DefaultCellStyle.SelectionBackColor
> や
> DefaultCellStyle.SelectionForeColor
> のようなものをイメージしています。
> どのような方法があるのか教えていただきたいのです。
これは OS 依存で無理っぽいです。
少なくとも ListView にフォーカスがあるうちは無理。
ListView からフォーカスが外れれば、選択行の色変更は可能です。
以下サンプルです。
ListView は View を Details にし、FullRowSelect を True、
MultiSelect を False に設定してます。
で、ボタンクリックイベントなら色は変わるが、SelectedIndexChanged イベント等では駄目。
Private Sub Button1_Click
(ByVal sender As System.Object, ByVal e As System.EventArgs)
Handles Button1.Click
For Each item As ListViewItem In ListView1.Items
If (item.Selected) Then
item.BackColor = Color.PeachPuff
item.ForeColor = Color.Red
Else
item.BackColor = SystemColors.Window
item.ForeColor = SystemColors.WindowText
End If
Next
End Sub
2010/01/18(Mon) 23:02:55 編集(投稿者)
2010/01/18(Mon) 23:01:06 編集(投稿者)
お疲れ様です。
後だしジャンケンのようで申し訳ないですが(その意思はありません)
jacoさんの参考になればと思い、簡単なサンプルを投稿させていただきました。
(DrawFocusRectangleは手抜きしています)
参考URL
ttp://msdn.microsoft.com/ja-jp/library/system.windows.forms.listview.drawsubitem(VS.80).aspx
' ListView1を配置してください
Public Class Form_ListViewTest
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
With Me.ListView1
.View = View.Details
.OwnerDraw = True
.Columns.Add("列1")
.Columns.Add("列2")
For i As Integer = 0 To 10
.Items.Add(New ListViewItem( _
New String() {"値1−" + i.ToString, "値2−" + i.ToString}))
Next
End With
MyBase.OnLoad(e)
End Sub
Private Sub ListView1_DrawColumnHeader(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawListViewColumnHeaderEventArgs) Handles ListView1.DrawColumnHeader
e.DrawDefault = True
End Sub
Private Sub ListView1_DrawItem(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawListViewItemEventArgs) Handles ListView1.DrawItem
If e.Item.Selected Then
e.Item.BackColor = Color.Orange
Else
e.Item.BackColor = SystemColors.Window
End If
If Me.ListView1.View <> View.Details Then
e.DrawBackground()
e.DrawText()
End If
End Sub
Private Sub ListView1_DrawSubItem(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
If e.Item.Selected Then
e.SubItem.ForeColor = Color.Red
Else
e.SubItem.ForeColor = SystemColors.WindowText
End If
e.DrawBackground()
e.DrawText()
End Sub
End Class
お疲れ様です。
GridLines = Trueに対応するため、
ListView1_DrawSubItemイベントハンドラを修正しました。
私のPCではうまく行きましたので、試してみてください。
Private Sub ListView1_DrawSubItem(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawListViewSubItemEventArgs) Handles ListView1.DrawSubItem
If e.Item.Selected Then
e.SubItem.ForeColor = Color.Red
Else
e.SubItem.ForeColor = SystemColors.WindowText
End If
e.DrawBackground()
e.DrawText()
If Me.ListView1.GridLines Then
Dim rect As Rectangle = e.Bounds
' この辺は苦し紛れ(座標の微調整)
rect.Offset(0, -SystemInformation.BorderSize.Height)
' 上・右・下の三方に線を描画
Dim points As Point() = {New Point(rect.Left, rect.Top), New Point(rect.Right, rect.Top), _
New Point(rect.Right, rect.Bottom), New Point(rect.Left, rect.Bottom)}
e.Graphics.DrawLines(SystemPens.ControlLight, points)
End If
End Sub
お疲れ様です。
以下のコードで試してみてください。
(参考URL)
ttp://msdn.microsoft.com/ja-jp/library/system.windows.forms.treeview.drawnode(VS.80).aspx
Public Class Form_TreeViewTest
Inherits Form
Dim WithEvents TreeView1 As New TreeView
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
With Me.TreeView1
.Dock = DockStyle.Fill
.DrawMode = TreeViewDrawMode.OwnerDrawText
With .Nodes.Add("ノード1")
.Nodes.Add("子ノード1")
.Nodes.Add("子ノード2")
.Nodes.Add("子ノード3")
End With
End With
Me.Controls.Add(Me.TreeView1)
MyBase.OnLoad(e)
End Sub
Private Sub TreeView1_DrawNode(ByVal sender As Object, _
ByVal e As System.Windows.Forms.DrawTreeNodeEventArgs) Handles TreeView1.DrawNode
Dim textColor As Color = SystemColors.WindowText
Dim backgroundColor As Color = SystemColors.Window
If e.Node.IsSelected Then
textColor = Color.Green
backgroundColor = Color.Orange
End If
Using backBrush As New SolidBrush(backgroundColor)
e.Graphics.FillRectangle(backBrush, e.Node.Bounds)
End Using
Using textBrush As New SolidBrush(textColor)
Dim nodeFont As Font = e.Node.NodeFont
If nodeFont Is Nothing Then
nodeFont = Me.TreeView1.Font
End If
e.Graphics.DrawString(e.Node.Text, nodeFont, textBrush, _
e.Node.Bounds.Left, e.Node.Bounds.Top + 1)
End Using
' Focus枠を描画(少し苦しいコード)
If e.Node.IsSelected Then
Using pen As New Pen(Color.Black)
Dim rect As Rectangle = e.Node.Bounds
Dim points As Point() = {New Point(rect.Left, rect.Top), _
New Point(rect.Right - 1, rect.Top), _
New Point(rect.Right - 1, rect.Bottom - 1), _
New Point(rect.Left, rect.Bottom - 1), _
New Point(rect.Left, rect.Top)}
e.Graphics.DrawLines(pen, points)
pen.Color = SystemColors.ControlLight
pen.DashStyle = Drawing2D.DashStyle.Dot
e.Graphics.DrawLines(pen, points)
End Using
End If
End Sub
End Class
お疲れ様です。
何箇所か苦しい処理があるコードですが、
試してみてください。
Public Class Form_TreeViewTest
Inherits Form
Dim WithEvents TreeView1 As New TreeViewEx
Protected Overrides Sub OnLoad(ByVal e As System.EventArgs)
With Me.TreeView1
.Dock = DockStyle.Fill
._executeFullRowSelect = True
.DrawMode = TreeViewDrawMode.OwnerDrawAll
With .Nodes.Add("ノード1")
.Nodes.Add("子ノード1")
With .Nodes.Add("子ノード2")
.Nodes.Add("孫ノード2−1")
.Nodes.Add("孫ノード2−2")
End With
.Nodes.Add("子ノード3")
End With
End With
Me.Controls.Add(Me.TreeView1)
MyBase.OnLoad(e)
End Sub
Private Class TreeViewEx
Inherits TreeView
Public _executeFullRowSelect As Boolean = False
Public _selectionForeColor As Color = Color.Blue
Public _selectionBackColor As Color = Color.Orange
Protected Overrides Sub WndProc(ByRef m As System.Windows.Forms.Message)
Const WM_PAINT As Integer = &HF
MyBase.WndProc(m)
' この辺りは苦しい。
If m.Msg = WM_PAINT AndAlso Me.DrawMode <> TreeViewDrawMode.Normal Then
Using g As Graphics = Me.CreateGraphics
' マウス位置のNodeを通常表示に
'(クリックしたNodeのText表示の数字部分が若干ずれるのはご了承下さい)
Dim info As TreeViewHitTestInfo = Me.HitTest(Me.PointToClient(Cursor.Position))
Dim nodeofcursorposition As TreeNode = info.Node
If nodeofcursorposition IsNot Nothing Then
Me._drawNormalNodeCore(g, nodeofcursorposition)
End If
' 選択Nodeのハイライト表示
Dim selectednode As TreeNode = Me.SelectedNode
Me._drawHighlightedNodeCore(g, selectednode)
Dim rowbound As Rectangle = Me._getRowBoundCore(selectednode.Bounds)
Me._drawFocusRectangleCore(g, rowbound)
End Using
End If
End Sub
Protected Overrides Sub OnDrawNode(ByVal e As System.Windows.Forms.DrawTreeNodeEventArgs)
Dim rowbound As Rectangle = Me._getRowBoundCore(e.Node.Bounds)
If e.Node.IsSelected Then
Me._drawBackGroundCore(e.Graphics, rowbound, Me._selectionBackColor)
End If
e.DrawDefault = True
MyBase.OnDrawNode(e)
End Sub
Private Function _getRowBoundCore(ByVal nodebound As Rectangle) As Rectangle
If Me._executeFullRowSelect Then
Return New Rectangle(0, nodebound.Top, Me.ClientSize.Width, nodebound.Height)
Else
Return nodebound
End If
End Function
Private Sub _drawNormalNodeCore(ByVal g As Graphics, ByVal node As TreeNode)
Me._drawBackGroundCore(g, node.Bounds, Me.BackColor)
Me._drawTextCore(g, node, Me.ForeColor)
End Sub
Private Sub _drawHighlightedNodeCore(ByVal g As Graphics, ByVal node As TreeNode)
Me._drawBackGroundCore(g, node.Bounds, Me._selectionBackColor)
Me._drawTextCore(g, node, Me._selectionForeColor)
End Sub
Private Sub _drawBackGroundCore(ByVal g As Graphics, _
ByVal bound As Rectangle, ByVal backgroundColor As Color)
Using backBrush As New SolidBrush(backgroundColor)
g.FillRectangle(backBrush, bound)
End Using
End Sub
Private Sub _drawTextCore(ByVal g As Graphics, _
ByVal node As TreeNode, ByVal textColor As Color)
Using textBrush As New SolidBrush(textColor)
Dim nodeFont As Font = node.NodeFont
If nodeFont Is Nothing Then
nodeFont = Me.Font
End If
g.DrawString(node.Text, nodeFont, textBrush, _
node.Bounds.Left, node.Bounds.Top + 1)
End Using
End Sub
' Focus枠を描画(少し苦しいコード)
Private Sub _drawFocusRectangleCore(ByVal g As Graphics, _
ByVal bound As Rectangle)
Using pen As New Pen(Color.Black)
Dim rect As Rectangle = bound
Dim points As Point() = {New Point(rect.Left, rect.Top), _
New Point(rect.Right - 1, rect.Top), _
New Point(rect.Right - 1, rect.Bottom - 1), _
New Point(rect.Left, rect.Bottom - 1), _
New Point(rect.Left, rect.Top)}
g.DrawLines(pen, points)
pen.Color = SystemColors.ControlLight
pen.DashStyle = Drawing2D.DashStyle.Dot
g.DrawLines(pen, points)
End Using
End Sub
End Class
End Class
分類:[.NET]
お世話になります。
タイトルどおりです。
ListViewの選択され、ハイライトになっている行の
背景色と文字色を変更したいです。
(複数行の選択はNGとしています。)
DataGridViewでいう
DefaultCellStyle.SelectionBackColor
や
DefaultCellStyle.SelectionForeColor
のようなものをイメージしています。
どのような方法があるのか教えていただきたいのです。
さらに上記を
SelectedIndexChanged(?)イベントで実行したいのですが
TabControlに配置した20個のListViewが対象になります。
やはり20個のイベントを書かなければならないのでしょうか?
一括してコーディングできる方法があれば
あわせて教えてください。
よろしくお願いします。