diff --git a/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml b/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml
index 6968dda..c097ad6 100644
--- a/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml
+++ b/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml
@@ -4,361 +4,375 @@
xmlns:models="using:Avalonia.PropertyGrid.Models"
xmlns:sys="clr-namespace:System;assembly=System.Runtime">
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
-
-
-
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml.cs b/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml.cs
index 14ad537..e33095c 100644
--- a/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml.cs
+++ b/Avalonia.PropertyGrid/Controls/PropertyGrid.axaml.cs
@@ -288,11 +288,10 @@ public class PropertyGrid : TemplatedControl
// Apply search filter
if (!string.IsNullOrWhiteSpace(_searchText))
{
- var searchLower = _searchText.ToLowerInvariant();
filtered = filtered.Where(p =>
- p.DisplayName.ToLowerInvariant().Contains(searchLower) ||
- (p.Category?.ToLowerInvariant().Contains(searchLower) ?? false) ||
- (p.Description?.ToLowerInvariant().Contains(searchLower) ?? false));
+ p.DisplayName.Contains(_searchText, StringComparison.OrdinalIgnoreCase) ||
+ (p.Category?.Contains(_searchText, StringComparison.OrdinalIgnoreCase) ?? false) ||
+ (p.Description?.Contains(_searchText, StringComparison.OrdinalIgnoreCase) ?? false));
}
// Populate flat list
diff --git a/Avalonia.PropertyGrid/Converters/ColorToBrushConverter.cs b/Avalonia.PropertyGrid/Converters/ColorToBrushConverter.cs
index 0743063..51bf4d2 100644
--- a/Avalonia.PropertyGrid/Converters/ColorToBrushConverter.cs
+++ b/Avalonia.PropertyGrid/Converters/ColorToBrushConverter.cs
@@ -8,8 +8,16 @@ namespace Avalonia.PropertyGrid.Controls;
///
/// Converts an Avalonia.Media.Color to a SolidColorBrush
///
-public class ColorToBrushConverter : IValueConverter
+public sealed class ColorToBrushConverter : IValueConverter
{
+ ///
+ /// Converts a Color to a SolidColorBrush.
+ ///
+ /// The Color value to convert.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// A SolidColorBrush with the specified color.
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Color color)
@@ -21,9 +29,17 @@ public class ColorToBrushConverter : IValueConverter
return new SolidColorBrush(Colors.Transparent);
}
+ ///
+ /// Converts a SolidColorBrush back to a Color.
+ ///
+ /// The SolidColorBrush value to convert back.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// The Color from the brush.
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
- if (value is SolidColorBrush brush && brush.Color != null)
+ if (value is SolidColorBrush brush)
{
return brush.Color;
}
diff --git a/Avalonia.PropertyGrid/Converters/NegateBoolConverter.cs b/Avalonia.PropertyGrid/Converters/NegateBoolConverter.cs
index 71f5744..fb42d44 100644
--- a/Avalonia.PropertyGrid/Converters/NegateBoolConverter.cs
+++ b/Avalonia.PropertyGrid/Converters/NegateBoolConverter.cs
@@ -7,8 +7,16 @@ namespace Avalonia.PropertyGrid.Controls;
///
/// Converts boolean value to its negation for two-way binding
///
-public class NegateBoolConverter : IValueConverter
+public sealed class NegateBoolConverter : IValueConverter
{
+ ///
+ /// Converts a boolean value to its negation.
+ ///
+ /// The boolean value to convert.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// The negated boolean value.
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is bool boolValue)
@@ -18,6 +26,14 @@ public class NegateBoolConverter : IValueConverter
return false;
}
+ ///
+ /// Converts a boolean value back to its negation (two-way binding).
+ ///
+ /// The boolean value to convert back.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// The negated boolean value.
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is bool boolValue)
diff --git a/Avalonia.PropertyGrid/Converters/NumericFormatConverter.cs b/Avalonia.PropertyGrid/Converters/NumericFormatConverter.cs
index c56fcbc..d0f6c98 100644
--- a/Avalonia.PropertyGrid/Converters/NumericFormatConverter.cs
+++ b/Avalonia.PropertyGrid/Converters/NumericFormatConverter.cs
@@ -7,8 +7,16 @@ namespace Avalonia.PropertyGrid.Controls;
///
/// Converts PropertyType to appropriate numeric format string
///
-public class NumericFormatConverter : IValueConverter
+public sealed class NumericFormatConverter : IValueConverter
{
+ ///
+ /// Converts a Type to an appropriate numeric format string.
+ ///
+ /// The Type to convert.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// A format string like "N2" for floating point or "N0" for integers.
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
@@ -26,6 +34,15 @@ public class NumericFormatConverter : IValueConverter
return "N0";
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// The value to convert back.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// Throws NotImplementedException.
+ /// This converter does not support ConvertBack.
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
diff --git a/Avalonia.PropertyGrid/Converters/PropertyGridConverters.cs b/Avalonia.PropertyGrid/Converters/PropertyGridConverters.cs
index df8239b..20f398c 100644
--- a/Avalonia.PropertyGrid/Converters/PropertyGridConverters.cs
+++ b/Avalonia.PropertyGrid/Converters/PropertyGridConverters.cs
@@ -7,7 +7,7 @@ namespace Avalonia.PropertyGrid.Controls;
///
/// Converts indent level to left margin
///
-public class IndentToMarginConverter : IValueConverter
+public sealed class IndentToMarginConverter : IValueConverter
{
///
/// Converts indent level to left margin.
@@ -33,7 +33,7 @@ public class IndentToMarginConverter : IValueConverter
///
/// Converts enum type to list of enum values
///
-public class EnumValuesConverter : IValueConverter
+public sealed class EnumValuesConverter : IValueConverter
{
///
/// Converts an enum type to an array of its values.
@@ -59,8 +59,16 @@ public class EnumValuesConverter : IValueConverter
///
/// Checks if a type is an enum
///
-public class IsEnumConverter : IValueConverter
+public sealed class IsEnumConverter : IValueConverter
{
+ ///
+ /// Checks if the provided type is an enum.
+ ///
+ /// The Type to check.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// True if the type is an enum, otherwise false.
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
@@ -70,6 +78,10 @@ public class IsEnumConverter : IValueConverter
return false;
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// This converter does not support ConvertBack.
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
@@ -79,8 +91,16 @@ public class IsEnumConverter : IValueConverter
///
/// Checks if a type is a simple type (string, number, bool, etc.)
///
-public class IsSimpleTypeConverter : IValueConverter
+public sealed class IsSimpleTypeConverter : IValueConverter
{
+ ///
+ /// Checks if the provided type is a simple type like string, number, DateTime, etc.
+ ///
+ /// The Type to check.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// True if the type is a simple type, otherwise false.
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
@@ -96,6 +116,10 @@ public class IsSimpleTypeConverter : IValueConverter
return false;
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// This converter does not support ConvertBack.
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
@@ -105,8 +129,16 @@ public class IsSimpleTypeConverter : IValueConverter
///
/// Checks if a type matches the specified type name
///
-public class TypeToBoolConverter : IValueConverter
+public sealed class TypeToBoolConverter : IValueConverter
{
+ ///
+ /// Checks if the type's name matches the specified parameter string.
+ ///
+ /// The Type to check.
+ /// The target type.
+ /// The type name to match against.
+ /// Culture information.
+ /// True if the type name matches, otherwise false.
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type && parameter is string typeName)
@@ -116,6 +148,10 @@ public class TypeToBoolConverter : IValueConverter
return false;
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// This converter does not support ConvertBack.
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
@@ -125,8 +161,16 @@ public class TypeToBoolConverter : IValueConverter
///
/// Converts Color to/from hex string representation
///
-public class ColorToStringConverter : IValueConverter
+public sealed class ColorToStringConverter : IValueConverter
{
+ ///
+ /// Converts a Color to a hex string representation.
+ ///
+ /// The Color to convert.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// A hex string representation of the color (e.g., "#AARRGGBB").
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Media.Color color)
@@ -136,6 +180,14 @@ public class ColorToStringConverter : IValueConverter
return value?.ToString();
}
+ ///
+ /// Converts a hex string back to a Color.
+ ///
+ /// The hex string to convert.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// The parsed Color, or Black if parsing fails.
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is string hexString && !string.IsNullOrWhiteSpace(hexString))
@@ -143,7 +195,7 @@ public class ColorToStringConverter : IValueConverter
try
{
hexString = hexString.Trim();
- if (!hexString.StartsWith("#"))
+ if (!hexString.StartsWith('#'))
hexString = "#" + hexString;
return Media.Color.Parse(hexString);
@@ -161,8 +213,16 @@ public class ColorToStringConverter : IValueConverter
///
/// Checks if a type is Color
///
-public class IsColorTypeConverter : IValueConverter
+public sealed class IsColorTypeConverter : IValueConverter
{
+ ///
+ /// Checks if the provided type is Avalonia.Media.Color.
+ ///
+ /// The Type to check.
+ /// The target type.
+ /// Optional "Invert" parameter to invert the result.
+ /// Culture information.
+ /// True if the type is Color (or inverted if parameter is "Invert"), otherwise false.
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
@@ -187,6 +247,10 @@ public class IsColorTypeConverter : IValueConverter
return false;
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// This converter does not support ConvertBack.
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
@@ -196,8 +260,16 @@ public class IsColorTypeConverter : IValueConverter
///
/// Checks if a type is numeric
///
-public class IsNumericTypeConverter : IValueConverter
+public sealed class IsNumericTypeConverter : IValueConverter
{
+ ///
+ /// Checks if the provided type is a numeric type (int, long, float, double, decimal, etc.).
+ ///
+ /// The Type to check.
+ /// The target type.
+ /// Optional "Invert" parameter to invert the result.
+ /// Culture information.
+ /// True if the type is numeric (or inverted if parameter is "Invert"), otherwise false.
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
@@ -225,6 +297,10 @@ public class IsNumericTypeConverter : IValueConverter
return false;
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// This converter does not support ConvertBack.
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
@@ -234,8 +310,16 @@ public class IsNumericTypeConverter : IValueConverter
///
/// Checks if a type is neither Color nor Numeric nor Boolean nor Enum (for fallback TextBox)
///
-public class IsOtherTypeConverter : IValueConverter
+public sealed class IsOtherTypeConverter : IValueConverter
{
+ ///
+ /// Checks if the type is not Color, Numeric, Boolean, or Enum (used for fallback TextBox editor).
+ ///
+ /// The Type to check.
+ /// The target type.
+ /// Optional parameter.
+ /// Culture information.
+ /// True if the type is not a special type, otherwise false.
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
@@ -255,6 +339,10 @@ public class IsOtherTypeConverter : IValueConverter
return true; // Default to showing TextBox
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// This converter does not support ConvertBack.
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
@@ -264,8 +352,16 @@ public class IsOtherTypeConverter : IValueConverter
///
/// Checks if a type is boolean
///
-public class IsBooleanTypeConverter : IValueConverter
+public sealed class IsBooleanTypeConverter : IValueConverter
{
+ ///
+ /// Checks if the provided type is boolean.
+ ///
+ /// The Type to check.
+ /// The target type.
+ /// Optional "Invert" parameter to invert the result.
+ /// Culture information.
+ /// True if the type is boolean (or inverted if parameter is "Invert"), otherwise false.
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (value is Type type)
@@ -290,6 +386,10 @@ public class IsBooleanTypeConverter : IValueConverter
return false;
}
+ ///
+ /// Not supported for this converter.
+ ///
+ /// This converter does not support ConvertBack.
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotImplementedException();
diff --git a/Avalonia.PropertyGrid/Editors/PropertyEditors.cs b/Avalonia.PropertyGrid/Editors/PropertyEditors.cs
index 12d7d4b..51c3918 100644
--- a/Avalonia.PropertyGrid/Editors/PropertyEditors.cs
+++ b/Avalonia.PropertyGrid/Editors/PropertyEditors.cs
@@ -266,7 +266,7 @@ public class DateTimeEditor : PropertyEditor
///
/// Converter for DateTime to DateTimeOffset
///
-internal class DateTimeToDateTimeOffsetConverter : Avalonia.Data.Converters.IValueConverter
+internal sealed class DateTimeToDateTimeOffsetConverter : Avalonia.Data.Converters.IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
{
diff --git a/Avalonia.PropertyGrid/Models/CategoryGroup.cs b/Avalonia.PropertyGrid/Models/CategoryGroup.cs
index 11e2a03..e27b48d 100644
--- a/Avalonia.PropertyGrid/Models/CategoryGroup.cs
+++ b/Avalonia.PropertyGrid/Models/CategoryGroup.cs
@@ -47,6 +47,10 @@ public class CategoryGroup : INotifyPropertyChanged
///
public int PropertyCount => Properties.Count;
+ ///
+ /// Raises the PropertyChanged event for the specified property.
+ ///
+ /// The name of the property that changed.
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
diff --git a/Avalonia.PropertyGrid/Models/PropertyItem.cs b/Avalonia.PropertyGrid/Models/PropertyItem.cs
index 9a4858b..dcac68a 100644
--- a/Avalonia.PropertyGrid/Models/PropertyItem.cs
+++ b/Avalonia.PropertyGrid/Models/PropertyItem.cs
@@ -182,7 +182,7 @@ public class PropertyItem : INotifyPropertyChanged
try
{
var hexString = value?.Trim() ?? "";
- if (!hexString.StartsWith("#"))
+ if (!hexString.StartsWith('#'))
hexString = "#" + hexString;
Value = Media.Color.Parse(hexString);
diff --git a/Examples/AdvancedExample/Models/AdvancedConfiguration.cs b/Examples/AdvancedExample/Models/AdvancedConfiguration.cs
index ffed645..d469637 100644
--- a/Examples/AdvancedExample/Models/AdvancedConfiguration.cs
+++ b/Examples/AdvancedExample/Models/AdvancedConfiguration.cs
@@ -223,7 +223,7 @@ public class NetworkSettings : INotifyPropertyChanged
{
private string _hostname = "api.example.com";
private int _port = 443;
- private bool _useProxy = false;
+ private bool _useProxy;
private string _proxyAddress = string.Empty;
[Display(Name = "Hostname", Description = "Server hostname or IP address")]
diff --git a/Examples/AdvancedExample/Program.cs b/Examples/AdvancedExample/Program.cs
index 02f182d..c4f296c 100644
--- a/Examples/AdvancedExample/Program.cs
+++ b/Examples/AdvancedExample/Program.cs
@@ -3,7 +3,7 @@ using System;
namespace AdvancedExample;
-class Program
+sealed class Program
{
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
diff --git a/Examples/QuickStartExample/Program.cs b/Examples/QuickStartExample/Program.cs
index 5c49989..43fe402 100644
--- a/Examples/QuickStartExample/Program.cs
+++ b/Examples/QuickStartExample/Program.cs
@@ -3,7 +3,7 @@ using Avalonia;
namespace QuickStartExample;
-class Program
+sealed class Program
{
[STAThread]
public static void Main(string[] args) => BuildAvaloniaApp()
diff --git a/PropertyGrid.slnx b/PropertyGrid.slnx
new file mode 100644
index 0000000..70d6cf6
--- /dev/null
+++ b/PropertyGrid.slnx
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+