using System;
using System.Collections.Generic;
using System.Linq;
using Avalonia;
using Avalonia.PropertyGrid.Services;
using JetBrains.Annotations;
using PropertyModels.ComponentModel;
using StabilityMatrix.Core.Extensions;
namespace StabilityMatrix.Avalonia.Controls;
///
[PublicAPI]
public class BetterPropertyGrid : global::Avalonia.PropertyGrid.Controls.PropertyGrid
{
protected override Type StyleKeyOverride => typeof(global::Avalonia.PropertyGrid.Controls.PropertyGrid);
public static readonly StyledProperty> ExcludedCategoriesProperty = AvaloniaProperty.Register<
BetterPropertyGrid,
IEnumerable
>("ExcludedCategories");
public IEnumerable ExcludedCategories
{
get => GetValue(ExcludedCategoriesProperty);
set => SetValue(ExcludedCategoriesProperty, value);
}
public static readonly StyledProperty> IncludedCategoriesProperty = AvaloniaProperty.Register<
BetterPropertyGrid,
IEnumerable
>("IncludedCategories");
public IEnumerable IncludedCategories
{
get => GetValue(IncludedCategoriesProperty);
set => SetValue(IncludedCategoriesProperty, value);
}
static BetterPropertyGrid()
{
// Register factories
CellEditFactoryService.Default.AddFactory(new ToggleSwitchCellEditFactory());
// Initialize localization and name resolver
LocalizationService.Default.AddExtraService(new PropertyGridLocalizationService());
ExcludedCategoriesProperty
.Changed
.AddClassHandler(
(grid, args) =>
{
if (args.NewValue is IEnumerable excludedCategories)
{
grid.FilterExcludeCategories(excludedCategories);
}
}
);
IncludedCategoriesProperty
.Changed
.AddClassHandler(
(grid, args) =>
{
if (args.NewValue is IEnumerable includedCategories)
{
grid.FilterIncludeCategories(includedCategories);
}
}
);
}
public void FilterExcludeCategories(IEnumerable excludedCategories)
{
// Get internal property `ViewModel` of internal type `PropertyGridViewModel`
var gridVm = this.GetProtectedProperty("ViewModel")!;
// Get public property `CategoryFilter`
var categoryFilter = gridVm.GetProtectedProperty("CategoryFilter")!;
categoryFilter.BeginUpdate();
// Uncheck All, then check all except All
categoryFilter.UnCheck(categoryFilter.All);
foreach (var mask in categoryFilter.Masks.Where(m => m != categoryFilter.All))
{
categoryFilter.Check(mask);
}
// Uncheck excluded categories
foreach (var mask in excludedCategories)
{
categoryFilter.UnCheck(mask);
}
categoryFilter.EndUpdate();
}
public void FilterIncludeCategories(IEnumerable includeCategories)
{
// Get internal property `ViewModel` of internal type `PropertyGridViewModel`
var gridVm = this.GetProtectedProperty("ViewModel")!;
// Get public property `CategoryFilter`
var categoryFilter = gridVm.GetProtectedProperty("CategoryFilter")!;
categoryFilter.BeginUpdate();
// Uncheck non-included categories
foreach (var mask in categoryFilter.Masks.Where(m => !includeCategories.Contains(m)))
{
categoryFilter.UnCheck(mask);
}
categoryFilter.UnCheck(categoryFilter.All);
// Check included categories
foreach (var mask in includeCategories)
{
categoryFilter.Check(mask);
}
categoryFilter.EndUpdate();
}
}