次の方法で共有


Use colors in WPF to show virtual memory fragmentation

In this post What is your computer doing with all that memory? Write your own memory browser is sample code that shows how to create a WPF grid view of a memory map of a process. You can click on a column header to sort, and you can see the various loaded images and even a binary display of the actual memory.

 

We can modify that code to show the data in color very easily, using the magic of Data Binding.

 

Paste the code from the prior post’s sample into a new VB WPF Application. You might have to change the class name from “Window1” to “MainWindow”

Hit Ctrl-F5 to run it, dbl click on a process to show the memory map of that process.

 

Now let’s add some color: we add a few lines of code in 2 segments: a class that implements IValueConverter, and some code to modify the Style of the items contained in the ListView

 

Paste this class at the end of the file:

 

Public Class VMBgd

    Implements IValueConverter

 

    Public Function Convert(

                ByVal value As Object,

                ByVal targetType As System.Type,

                ByVal parameter As Object,

                ByVal culture As System.Globalization.CultureInfo

                ) As Object Implements System.Windows.Data.IValueConverter.Convert

        Dim bgColor = Brushes.White

        Dim lvitem = CType(value, ListViewItem)

        Dim memType = CStr(ComponentModel.TypeDescriptor.

            GetProperties(lvitem.DataContext)("Type").

            GetValue(lvitem.DataContext)) ' get the value of the "Type" column

        Select Case memType

            Case "MEM_IMAGE"

                bgColor = Brushes.Violet

            Case "MEM_PRIVATE"

                bgColor = Brushes.Yellow

            Case "MEM_MAPPED"

                bgColor = Brushes.PaleTurquoise

        End Select

 

        Return bgColor

    End Function

 

    Public Function ConvertBack(

                    ByVal value As Object,

                    ByVal targetType As System.Type,

                    ByVal parameter As Object,

                    ByVal culture As System.Globalization.CultureInfo

                    ) As Object Implements System.Windows.Data.IValueConverter.ConvertBack

        Throw New NotImplementedException

    End Function

End Class

 

 

 

 

 

And around line 160, find the “dp.Children.Add(New Browse” line and replace with this code:

 

 

                'dp.Children.Add(New Browse(q, _

                ' delMouseMove:=AddressOf On_VirtmemMouseMove, _

                ' deldblclick:=AddressOf On_VirtmemDblClick))

 

                Dim brow = New Browse(q, _

                                        delMouseMove:=AddressOf On_VirtmemMouseMove, _

                                        deldblclick:=AddressOf On_VirtmemDblClick)

                Dim bgStyle = New Windows.Style(

                              GetType(ListViewItem)

                              ) ' style for a ListViewItem

                Dim binder = New Binding With {

                    .Converter = New VMBgd,

                    .RelativeSource = New RelativeSource(RelativeSourceMode.Self),

                    .Mode = BindingMode.OneTime

                } ' Bind our color converter

                Dim bgSetter = New Setter(ListViewItem.BackgroundProperty, Brushes.White) With {

                    .Value = binder

                } ' BG bound to our binder

                bgStyle.Setters.Add(bgSetter)

                bgStyle.Setters.Add(

                    New Setter(

                        ListViewItem.MarginProperty,

                        New Thickness(0))

                    ) ' space between rows

                bgStyle.Setters.Add(

                    New Setter(

                        ListViewItem.BorderThicknessProperty,

                        New Thickness(0))

                    ) ' space between rows

 

 

                brow.ItemContainerStyle = bgStyle

 

                dp.Children.Add(brow)

 

 

 

Now run it, select a process and see the colors! Click on BaseAddress to sort and browse around to groups of the Violet colored images and see how many of them are separated by a white Free region. If this region is less than 64k (0x10000), then that Virtual Memory address range fragment is unusable.

 

The pasted class VMBgd has the ability to return a color given an object. The TypeDescriptor class is used to get the properties of the ListView’s DataContext, which are the columns of the view. GetProperties returns a collection of PropertyDescriptors, and we want the Value of “Type” (which is the column indicating Memory Allocation Type from the Linq query (around line 156)) member.

 

An instance of the class is bound to the ListViewItem background color via a Setter in the Windows.Style for the ListView.ItemContainerStyle. When rendering the data, when the Background property is accessed, and it’s bound to our Converter which returns the desired color.

 

As an exercise, make these unusable regions a different color.

 

See also:

Remove double spaces from pasted code samples in blog