- 題名: 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個のイベントを書かなければならないのでしょうか?
一括してコーディングできる方法があれば
あわせて教えてください。
よろしくお願いします。