diff --git a/ILSpy/Metadata/MetadataColumnBuilder.cs b/ILSpy/Metadata/MetadataColumnBuilder.cs
index 85045663c..a5d7e43e1 100644
--- a/ILSpy/Metadata/MetadataColumnBuilder.cs
+++ b/ILSpy/Metadata/MetadataColumnBuilder.cs
@@ -59,15 +59,15 @@ namespace ILSpy.Metadata
{
ArgumentNullException.ThrowIfNull(entryType);
return descriptorCache.GetOrAdd(entryType, BuildDescriptors)
- .Select(d => BuildColumn(d, filter: null))
+ .Select(BuildColumn)
.ToArray();
}
///
/// Populates with both Columns and
- /// ColumnFilters in matched order. Each column's header is a vertical pair —
- /// the column name above a small TextBox bound two-way to the column's filter — so
- /// the user can filter every column independently and the predicate ANDs the lot.
+ /// ColumnFilters in matched order. The view renders a column-aligned filter
+ /// row above the grid bound to the page's ColumnFilters; the predicate ANDs
+ /// every non-empty filter against its own column.
///
public static void Populate(MetadataTablePageModel page) => Populate(page, typeof(TEntry));
@@ -80,9 +80,8 @@ namespace ILSpy.Metadata
var columns = new List(descriptors.Length);
foreach (var d in descriptors)
{
- var filter = new ColumnFilter(d.Name);
- page.ColumnFilters.Add(filter);
- columns.Add(BuildColumn(d, filter));
+ page.ColumnFilters.Add(new ColumnFilter(d.Name));
+ columns.Add(BuildColumn(d));
}
page.Columns = columns;
}
@@ -103,53 +102,16 @@ namespace ILSpy.Metadata
return list.ToArray();
}
- static DataGridColumn BuildColumn(ColumnDescriptor d, ColumnFilter? filter)
+ static DataGridColumn BuildColumn(ColumnDescriptor d)
{
var column = d.Info?.Kind == ColumnKind.Token
? (DataGridColumn)BuildTokenColumn(d.Property, d.Info)
: BuildTextColumn(d.Property, d.Info);
- column.Header = filter is null ? d.Name : (object)BuildHeader(d.Name, filter);
- // Header is a Panel when filters are wired, so callers can't recover the column
- // name via Header.ToString(). Stash the name on Tag for hover-tooltip lookup,
- // "Go to token" context-menu resolution, and any future cell-level navigation.
+ column.Header = d.Name;
column.Tag = d.Name;
return column;
}
- static Control BuildHeader(string columnName, ColumnFilter filter)
- {
- var label = new TextBlock {
- Text = columnName,
- FontWeight = FontWeight.SemiBold,
- HorizontalAlignment = HorizontalAlignment.Stretch,
- };
- var box = new TextBox {
- MinHeight = 0,
- Padding = new Thickness(2, 1),
- Margin = new Thickness(0, 2, 0, 0),
- FontWeight = FontWeight.Normal,
- HorizontalAlignment = HorizontalAlignment.Stretch,
- Text = filter.Text,
- };
- // Wire TextBox <-> ColumnFilter imperatively. Avalonia's INPC binding plugin
- // holds a WeakReference to the source and resolves the target lazily; for
- // Header-hosted controls it reliably comes back null on write-back, throwing
- // "Non-static method requires a target" out of PropertyInfo.SetValue. The plain
- // event subscription side-steps the weak-ref machinery.
- box.TextChanged += (_, _) => {
- if (filter.Text != box.Text)
- filter.Text = box.Text;
- };
- filter.PropertyChanged += (_, e) => {
- if (e.PropertyName == nameof(ColumnFilter.Text) && box.Text != filter.Text)
- box.Text = filter.Text;
- };
- return new StackPanel {
- Orientation = Orientation.Vertical,
- Children = { label, box },
- };
- }
-
static DataGridTextColumn BuildTextColumn(PropertyInfo prop, ColumnInfoAttribute? info)
{
var binding = new Binding(prop.Name) { Mode = BindingMode.OneWay };
diff --git a/ILSpy/Views/MetadataTablePage.axaml b/ILSpy/Views/MetadataTablePage.axaml
index cc190d1b0..b9998060a 100644
--- a/ILSpy/Views/MetadataTablePage.axaml
+++ b/ILSpy/Views/MetadataTablePage.axaml
@@ -7,21 +7,30 @@
x:Class="ILSpy.Views.MetadataTablePage"
x:DataType="vm:MetadataTablePageModel">
-
-
+
+
+
+
+
+
+
diff --git a/ILSpy/Views/MetadataTablePage.axaml.cs b/ILSpy/Views/MetadataTablePage.axaml.cs
index 195b42f35..4ddf4bcb1 100644
--- a/ILSpy/Views/MetadataTablePage.axaml.cs
+++ b/ILSpy/Views/MetadataTablePage.axaml.cs
@@ -25,6 +25,7 @@ using Avalonia;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Input;
+using Avalonia.Layout;
using Avalonia.Markup.Xaml;
using Avalonia.VisualTree;
@@ -165,11 +166,13 @@ namespace ILSpy.Views
// the new schema has more columns than the old one.
grid.ItemsSource = Array.Empty