Browse Source

Fix #2151: Improve performance of Metadata DataGridCell

pull/2176/head
Siegfried Pammer 5 years ago
parent
commit
0f5e46336f
  1. 43
      ILSpy/Commands/DecompileCommand.cs
  2. 3
      ILSpy/ILSpy.csproj
  3. 1
      ILSpy/Metadata/CoffHeaderTreeNode.cs
  4. 59
      ILSpy/Metadata/DataGridCustomTextColumn.cs
  5. 101
      ILSpy/Metadata/GoToTokenCommand.cs
  6. 46
      ILSpy/Metadata/Helpers.cs
  7. 119
      ILSpy/Metadata/MetaDataGrid.cs
  8. 45
      ILSpy/Metadata/MetadataTableViews.xaml
  9. 10
      ILSpy/Metadata/OptionalHeaderTreeNode.cs

43
ILSpy/Commands/DecompileCommand.cs

@ -16,15 +16,9 @@ @@ -16,15 +16,9 @@
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata.Ecma335;
using System.Windows.Controls;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.Decompiler.TypeSystem;
using ICSharpCode.ILSpy.Metadata;
using ICSharpCode.ILSpy.Properties;
using ICSharpCode.ILSpy.TreeNodes;
@ -73,41 +67,4 @@ namespace ICSharpCode.ILSpy.Commands @@ -73,41 +67,4 @@ namespace ICSharpCode.ILSpy.Commands
MainWindow.Instance.JumpToReference(selection);
}
}
[ExportContextMenuEntry(Header = nameof(Resources.GoToToken), Order = 10)]
class GoToToken : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
int token = GetSelectedToken(context.DataGrid, out PEFile module).Value;
MainWindow.Instance.JumpToReference(new EntityReference("metadata", module, MetadataTokens.Handle(token)));
}
public bool IsEnabled(TextViewContext context)
{
return true;
}
public bool IsVisible(TextViewContext context)
{
return context.DataGrid?.Name == "MetadataView" && GetSelectedToken(context.DataGrid, out _) != null;
}
private int? GetSelectedToken(DataGrid grid, out PEFile module)
{
module = null;
if (grid == null)
return null;
var cell = grid.CurrentCell;
if (!cell.IsValid)
return null;
Type type = cell.Item.GetType();
var property = type.GetProperty(cell.Column.Header.ToString());
var moduleField = type.GetField("module", BindingFlags.NonPublic | BindingFlags.Instance);
if (property == null || property.PropertyType != typeof(int) || !property.GetCustomAttributes(false).Any(a => a is StringFormatAttribute sf && sf.Format == "X8"))
return null;
module = (PEFile)moduleField.GetValue(cell.Item);
return (int)property.GetValue(cell.Item);
}
}
}

3
ILSpy/ILSpy.csproj

@ -118,6 +118,7 @@ @@ -118,6 +118,7 @@
<Compile Include="Commands\DisassembleAllCommand.cs" />
<Compile Include="Commands\ExitCommand.cs" />
<Compile Include="Commands\CommandWrapper.cs" />
<Compile Include="Metadata\GoToTokenCommand.cs" />
<Compile Include="Commands\ILSpyCommands.cs" />
<Compile Include="Commands\IProtocolHandler.cs" />
<Compile Include="Commands\ManageAssemblyListsCommand.cs" />
@ -173,7 +174,6 @@ @@ -173,7 +174,6 @@
<SubType>Code</SubType>
<Generator>MSBuild:Compile</Generator>
</Compile>
<Compile Include="Metadata\DataGridCustomTextColumn.cs" />
<Compile Include="Metadata\DebugTables\LocalConstantTableTreeNode.cs">
<SubType>Code</SubType>
<Generator>MSBuild:Compile</Generator>
@ -209,6 +209,7 @@ @@ -209,6 +209,7 @@
<Compile Include="Metadata\FlagsFilterControl.xaml.cs" />
<Compile Include="Metadata\FlagsTooltip.xaml.cs" />
<Compile Include="Metadata\HexFilterControl.xaml.cs" />
<Compile Include="Metadata\MetaDataGrid.cs" />
<Compile Include="Metadata\MetadataProtocolHandler.cs" />
<Compile Include="Metadata\MetadataTableTreeNode.cs" />
<Compile Include="Metadata\DebugMetadataTreeNode.cs" />

1
ILSpy/Metadata/CoffHeaderTreeNode.cs

@ -59,6 +59,7 @@ namespace ICSharpCode.ILSpy.Metadata @@ -59,6 +59,7 @@ namespace ICSharpCode.ILSpy.Metadata
AutoGenerateColumns = false,
CanUserAddRows = false,
CanUserDeleteRows = false,
GridLinesVisibility = DataGridGridLinesVisibility.None,
RowDetailsTemplateSelector = new CharacteristicsDataTemplateSelector(),
RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Visible
};

59
ILSpy/Metadata/DataGridCustomTextColumn.cs

@ -1,59 +0,0 @@ @@ -1,59 +0,0 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
namespace ICSharpCode.ILSpy.Metadata
{
class DataGridCustomTextColumn : DataGridTextColumn
{
public BindingBase ToolTipBinding { get; set; }
protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
{
TextBox textBox = new TextBox() { Style = (Style)MetadataTableViews.Instance["DataGridCustomTextColumnTextBoxStyle"] };
BindingOperations.SetBinding(textBox, TextBox.TextProperty, Binding);
if (ToolTipBinding != null)
{
textBox.MouseMove += TextBox_MouseMove;
}
textBox.GotFocus += TextBox_GotFocus;
return textBox;
}
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
TextBox tb = (TextBox)sender;
var cell = tb.GetParent<DataGridCell>();
var row = cell.GetParent<DataGridRow>();
row.IsSelected = cell.IsSelected = true;
}
private void TextBox_MouseMove(object sender, MouseEventArgs e)
{
e.Handled = true;
var textBox = (TextBox)sender;
BindingOperations.SetBinding(textBox, TextBox.ToolTipProperty, ToolTipBinding);
textBox.MouseMove -= TextBox_MouseMove;
}
}
}

101
ILSpy/Metadata/GoToTokenCommand.cs

@ -0,0 +1,101 @@ @@ -0,0 +1,101 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata.Ecma335;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using ICSharpCode.Decompiler.Metadata;
using ICSharpCode.ILSpy.Metadata;
using ICSharpCode.ILSpy.Properties;
namespace ICSharpCode.ILSpy.Commands
{
[ExportContextMenuEntry(Header = nameof(Resources.GoToToken), Order = 10)]
class GoToTokenCommand : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
int token = GetSelectedToken(context.DataGrid, out PEFile module).Value;
MainWindow.Instance.JumpToReference(new EntityReference("metadata", module, MetadataTokens.Handle(token)));
}
public bool IsEnabled(TextViewContext context)
{
return true;
}
public bool IsVisible(TextViewContext context)
{
return context.DataGrid?.Name == "MetadataView" && GetSelectedToken(context.DataGrid, out _) != null;
}
private int? GetSelectedToken(DataGrid grid, out PEFile module)
{
module = null;
if (grid == null)
return null;
var cell = grid.CurrentCell;
if (!cell.IsValid)
return null;
Type type = cell.Item.GetType();
var property = type.GetProperty(cell.Column.Header.ToString());
var moduleField = type.GetField("module", BindingFlags.NonPublic | BindingFlags.Instance);
if (property == null || property.PropertyType != typeof(int) || !property.GetCustomAttributes(false).Any(a => a is StringFormatAttribute sf && sf.Format == "X8"))
return null;
module = (PEFile)moduleField.GetValue(cell.Item);
return (int)property.GetValue(cell.Item);
}
}
[ExportContextMenuEntry(Header = nameof(Resources.Copy), Order = 10)]
class CopyCommand : IContextMenuEntry
{
public void Execute(TextViewContext context)
{
string content = GetSelectedCellContent(context.DataGrid, context.MousePosition);
Clipboard.SetText(content);
}
public bool IsEnabled(TextViewContext context)
{
return true;
}
public bool IsVisible(TextViewContext context)
{
return context.DataGrid?.Name == "MetadataView"
&& GetSelectedCellContent(context.DataGrid, context.MousePosition) != null;
}
private string GetSelectedCellContent(DataGrid grid, Point position)
{
position = grid.PointFromScreen(position);
var hit = VisualTreeHelper.HitTest(grid, position);
if (hit == null)
return null;
var cell = hit.VisualHit.GetParent<DataGridCell>();
return (cell?.Content as TextBlock)?.Text;
}
}
}

46
ILSpy/Metadata/Helpers.cs

@ -57,21 +57,15 @@ namespace ICSharpCode.ILSpy.Metadata @@ -57,21 +57,15 @@ namespace ICSharpCode.ILSpy.Metadata
RowHeaderWidth = 0,
EnableColumnVirtualization = true,
EnableRowVirtualization = true,
RowHeight = 20,
IsReadOnly = true,
SelectionMode = DataGridSelectionMode.Single,
SelectionUnit = DataGridSelectionUnit.CellOrRowHeader,
SelectionUnit = DataGridSelectionUnit.FullRow,
SelectedTreeNode = selectedNode,
CellStyle = new Style {
Setters = {
new Setter {
Property = Control.BorderThicknessProperty,
Value = new Thickness(0)
}
}
}
VerticalContentAlignment = VerticalAlignment.Center,
CellStyle = (Style)MetadataTableViews.Instance["DataGridCellStyle"]
};
ContextMenuProvider.Add(view);
ScrollViewer.SetIsDeferredScrollingEnabled(view, true);
DataGridFilter.SetIsAutoFilterEnabled(view, true);
DataGridFilter.SetContentFilterFactory(view, new RegexContentFilterFactory());
}
@ -88,18 +82,6 @@ namespace ICSharpCode.ILSpy.Metadata @@ -88,18 +82,6 @@ namespace ICSharpCode.ILSpy.Metadata
return view;
}
class MetaDataGrid : DataGrid, IHaveState
{
public ILSpyTreeNode SelectedTreeNode { get; set; }
public ViewState GetState()
{
return new ViewState {
DecompiledNodes = SelectedTreeNode == null ? null : new HashSet<ILSpyTreeNode>(new[] { SelectedTreeNode })
};
}
}
private static void View_AutoGeneratedColumns(object sender, EventArgs e)
{
((DataGrid)sender).AutoGeneratedColumns -= View_AutoGeneratedColumns;
@ -109,24 +91,21 @@ namespace ICSharpCode.ILSpy.Metadata @@ -109,24 +91,21 @@ namespace ICSharpCode.ILSpy.Metadata
private static void View_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)
{
var binding = new Binding(e.PropertyName) { Mode = BindingMode.OneWay };
e.Column = new DataGridCustomTextColumn() {
e.Column = new DataGridTextColumn() {
Header = e.PropertyName,
Binding = binding,
ToolTipBinding = new Binding(e.PropertyName + "Tooltip") { Mode = BindingMode.OneWay }
Binding = binding
};
switch (e.PropertyName)
{
case "RID":
case "Meaning":
e.Column.SetTemplate((ControlTemplate)MetadataTableViews.Instance["DefaultFilter"]);
((DataGridCustomTextColumn)e.Column).ToolTipBinding = null;
break;
case "Token":
case "Offset":
case "RVA":
binding.StringFormat = "X8";
e.Column.SetTemplate((ControlTemplate)MetadataTableViews.Instance["HexFilter"]);
((DataGridCustomTextColumn)e.Column).ToolTipBinding = null;
break;
default:
e.Cancel = e.PropertyName.Contains("Tooltip");
@ -147,13 +126,15 @@ namespace ICSharpCode.ILSpy.Metadata @@ -147,13 +126,15 @@ namespace ICSharpCode.ILSpy.Metadata
if (descriptor.PropertyType.IsEnum)
{
binding.Converter = new UnderlyingEnumValueConverter();
column.SetTemplate((ControlTemplate)MetadataTableViews.Instance[descriptor.PropertyType.Name + "Filter"]);
string key = descriptor.PropertyType.Name + "Filter";
column.SetTemplate((ControlTemplate)MetadataTableViews.Instance[key]);
}
var stringFormat = descriptor.Attributes.OfType<StringFormatAttribute>().FirstOrDefault();
if (stringFormat != null)
{
binding.StringFormat = stringFormat.Format;
if (!descriptor.PropertyType.IsEnum && stringFormat.Format.StartsWith("X", StringComparison.OrdinalIgnoreCase))
if (!descriptor.PropertyType.IsEnum
&& stringFormat.Format.StartsWith("X", StringComparison.OrdinalIgnoreCase))
{
column.SetTemplate((ControlTemplate)MetadataTableViews.Instance["HexFilter"]);
}
@ -210,9 +191,12 @@ namespace ICSharpCode.ILSpy.Metadata @@ -210,9 +191,12 @@ namespace ICSharpCode.ILSpy.Metadata
return (EntityHandle)fromTypeDefOrRefTag.Invoke(null, new object[] { tag });
}
public static int ComputeCodedTokenSize(this MetadataReader metadata, int largeRowSize, TableMask mask)
public static int ComputeCodedTokenSize(this MetadataReader metadata, int largeRowSize,
TableMask mask)
{
return (int)computeCodedTokenSize.Invoke(metadata, new object[] { largeRowSize, rowCounts.GetValue(metadata), (ulong)mask });
return (int)computeCodedTokenSize.Invoke(metadata, new object[] {
largeRowSize, rowCounts.GetValue(metadata), (ulong)mask }
);
}
class UnderlyingEnumValueConverter : IValueConverter

119
ILSpy/Metadata/MetaDataGrid.cs

@ -0,0 +1,119 @@ @@ -0,0 +1,119 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using ICSharpCode.AvalonEdit.Rendering;
using ICSharpCode.ILSpy.TextView;
using ICSharpCode.ILSpy.TreeNodes;
using ICSharpCode.ILSpy.ViewModels;
namespace ICSharpCode.ILSpy.Metadata
{
class MetaDataGrid : DataGrid, IHaveState
{
private readonly MouseHoverLogic hoverLogic;
private ToolTip toolTip;
public ILSpyTreeNode SelectedTreeNode { get; set; }
public MetaDataGrid()
{
this.hoverLogic = new MouseHoverLogic(this);
this.hoverLogic.MouseHover += HoverLogic_MouseHover;
this.hoverLogic.MouseHoverStopped += HoverLogic_MouseHoverStopped;
}
private void HoverLogic_MouseHoverStopped(object sender, System.Windows.Input.MouseEventArgs e)
{
// Non-popup tooltips get closed as soon as the mouse starts moving again
if (toolTip != null)
{
toolTip.IsOpen = false;
e.Handled = true;
}
}
private void HoverLogic_MouseHover(object sender, System.Windows.Input.MouseEventArgs e)
{
var position = e.GetPosition(this);
var hit = VisualTreeHelper.HitTest(this, position);
if (hit == null)
{
return;
}
var cell = hit.VisualHit.GetParent<DataGridCell>();
if (cell == null)
return;
var data = cell.DataContext;
var name = (string)cell.Column.Header;
if (toolTip == null)
{
toolTip = new ToolTip();
toolTip.Closed += ToolTipClosed;
}
toolTip.PlacementTarget = this; // required for property inheritance
var pi = data?.GetType().GetProperty(name + "Tooltip");
if (pi == null)
return;
object tooltip = pi.GetValue(data);
if (tooltip is string s)
{
if (string.IsNullOrWhiteSpace(s))
return;
toolTip.Content = new TextBlock {
Text = s,
TextWrapping = TextWrapping.Wrap
};
}
else if (tooltip != null)
{
toolTip.Content = tooltip;
}
else
{
return;
}
e.Handled = true;
toolTip.IsOpen = true;
}
private void ToolTipClosed(object sender, RoutedEventArgs e)
{
if (toolTip == sender)
{
toolTip = null;
}
}
public ViewState GetState()
{
return new ViewState {
DecompiledNodes = SelectedTreeNode == null
? null
: new HashSet<ILSpyTreeNode>(new[] { SelectedTreeNode })
};
}
}
}

45
ILSpy/Metadata/MetadataTableViews.xaml

@ -8,30 +8,31 @@ @@ -8,30 +8,31 @@
xmlns:srm="clr-namespace:System.Reflection;assembly=System.Reflection.Metadata"
xmlns:dgx="urn:tom-englert.de/DataGridExtensions">
<Style x:Key="DataGridCustomTextColumnTextBoxStyle" TargetType="TextBox">
<Setter Property="IsReadOnly" Value="True" />
<Setter Property="IsReadOnlyCaretVisible" Value="True" />
<Style x:Key="DataGridCellStyle" TargetType="{x:Type DataGridCell}">
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Padding" Value="2" />
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="False" />
<Condition Property="IsFocused" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="Background" Value="Transparent" />
</MultiTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource AncestorType=DataGridCell}}" Value="True" />
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
<Condition Binding="{Binding IsFocused, RelativeSource={RelativeSource Mode=Self}}" Value="False" />
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" Value="White" />
</MultiDataTrigger>
</Style.Triggers>
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridCell}">
<Border x:Name="Bd"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}"
SnapsToDevicePixels="True">
<ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
ContentStringFormat="{TemplateBinding ContentStringFormat}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="DefaultFilter">
<Grid>
<Control Style="{DynamicResource {x:Static dgx:DataGridFilter.IconStyleKey}}" />

10
ILSpy/Metadata/OptionalHeaderTreeNode.cs

@ -51,11 +51,11 @@ namespace ICSharpCode.ILSpy.Metadata @@ -51,11 +51,11 @@ namespace ICSharpCode.ILSpy.Metadata
dataGrid.RowDetailsTemplateSelector = new DllCharacteristicsDataTemplateSelector();
dataGrid.RowDetailsVisibilityMode = DataGridRowDetailsVisibilityMode.Visible;
dataGrid.AutoGenerateColumns = false;
dataGrid.Columns.Add(new DataGridCustomTextColumn { Header = "Member", Binding = new Binding("Member") { Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridCustomTextColumn { Header = "Offset", Binding = new Binding("Offset") { StringFormat = "X8", Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridCustomTextColumn { Header = "Size", Binding = new Binding("Size") { Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridCustomTextColumn { Header = "Value", Binding = new Binding(".") { Converter = ByteWidthConverter.Instance, Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridCustomTextColumn { Header = "Meaning", Binding = new Binding("Meaning") { Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridTextColumn { Header = "Member", Binding = new Binding("Member") { Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridTextColumn { Header = "Offset", Binding = new Binding("Offset") { StringFormat = "X8", Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridTextColumn { Header = "Size", Binding = new Binding("Size") { Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridTextColumn { Header = "Value", Binding = new Binding(".") { Converter = ByteWidthConverter.Instance, Mode = BindingMode.OneWay } });
dataGrid.Columns.Add(new DataGridTextColumn { Header = "Meaning", Binding = new Binding("Meaning") { Mode = BindingMode.OneWay } });
var headers = module.Reader.PEHeaders;
var reader = module.Reader.GetEntireImage().GetReader(headers.PEHeaderStartOffset, 128);

Loading…
Cancel
Save