Refactor PropertyGrid UI, converters, and solution setup
- Improved PropertyGrid.axaml formatting and control styles; ensured spinner buttons are always visible and ColorPicker layouts are flexible; disabled horizontal scrolling in property list. - Reformatted property editors and group/category display for clarity. - Made all value converters sealed, added XML docs, and updated ConvertBack to throw NotImplementedException where unsupported. - Enhanced search logic to use StringComparison.OrdinalIgnoreCase. - Minor code style fixes (e.g., char literals for string checks). - Removed default value assignment for _useProxy in AdvancedConfiguration.cs. - Updated Program.cs in examples to use sealed Program classes. - Added PropertyGrid.slnx to organize solution and projects.
This commit is contained in:
@@ -10,6 +10,20 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Design.PreviewWith>
|
</Design.PreviewWith>
|
||||||
|
|
||||||
|
<!-- Force NumericUpDown spinner buttons to always be visible -->
|
||||||
|
<Style Selector="controls|PropertyGrid NumericUpDown">
|
||||||
|
<Setter Property="AllowSpin" Value="True" />
|
||||||
|
<Setter Property="ShowButtonSpinner" Value="True" />
|
||||||
|
<Setter Property="ButtonSpinnerLocation" Value="Right" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style Selector="controls|PropertyGrid NumericUpDown /template/ TextBox#PART_TextBox">
|
||||||
|
<Setter Property="MinWidth" Value="0" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="controls|PropertyGrid ColorPicker /template/ DropDownButton /template/ PathIcon#DropDownGlyph">
|
||||||
|
<Setter Property="IsVisible" Value="False" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
<Style Selector="controls|PropertyGrid">
|
<Style Selector="controls|PropertyGrid">
|
||||||
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltHighBrush}" />
|
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltHighBrush}" />
|
||||||
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseMediumLowBrush}" />
|
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseMediumLowBrush}" />
|
||||||
@@ -41,7 +55,7 @@
|
|||||||
|
|
||||||
<!-- Properties List -->
|
<!-- Properties List -->
|
||||||
<ScrollViewer Grid.Row="1"
|
<ScrollViewer Grid.Row="1"
|
||||||
HorizontalScrollBarVisibility="Auto"
|
HorizontalScrollBarVisibility="Disabled"
|
||||||
VerticalScrollBarVisibility="Auto">
|
VerticalScrollBarVisibility="Auto">
|
||||||
<Panel>
|
<Panel>
|
||||||
<!-- Category View -->
|
<!-- Category View -->
|
||||||
@@ -67,14 +81,14 @@
|
|||||||
<!-- Right Arrow (collapsed/closed state) -->
|
<!-- Right Arrow (collapsed/closed state) -->
|
||||||
<Path IsVisible="{Binding !IsExpanded}"
|
<Path IsVisible="{Binding !IsExpanded}"
|
||||||
Data="M 4,2 L 10,8 L 4,14 Z"
|
Data="M 4,2 L 10,8 L 4,14 Z"
|
||||||
Fill="White"
|
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
|
||||||
Width="12" Height="12"
|
Width="12" Height="12"
|
||||||
Stretch="Uniform" />
|
Stretch="Uniform" />
|
||||||
|
|
||||||
<!-- Down Arrow (expanded/open state) -->
|
<!-- Down Arrow (expanded/open state) -->
|
||||||
<Path IsVisible="{Binding IsExpanded}"
|
<Path IsVisible="{Binding IsExpanded}"
|
||||||
Data="M 2,4 L 8,10 L 14,4 Z"
|
Data="M 2,4 L 8,10 L 14,4 Z"
|
||||||
Fill="White"
|
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
|
||||||
Width="12" Height="12"
|
Width="12" Height="12"
|
||||||
Stretch="Uniform" />
|
Stretch="Uniform" />
|
||||||
</Panel>
|
</Panel>
|
||||||
@@ -124,7 +138,7 @@
|
|||||||
Width="16" Height="16"
|
Width="16" Height="16"
|
||||||
Padding="0"
|
Padding="0"
|
||||||
VerticalAlignment="Center">
|
VerticalAlignment="Center">
|
||||||
<Panel>
|
<Panel >
|
||||||
<!-- Right Arrow (collapsed/closed state) -->
|
<!-- Right Arrow (collapsed/closed state) -->
|
||||||
<Path IsVisible="{Binding !IsExpanded}"
|
<Path IsVisible="{Binding !IsExpanded}"
|
||||||
Data="M 4,2 L 10,8 L 4,14 Z"
|
Data="M 4,2 L 10,8 L 4,14 Z"
|
||||||
@@ -160,30 +174,30 @@
|
|||||||
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
|
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
|
||||||
BorderThickness="0,0,0,1">
|
BorderThickness="0,0,0,1">
|
||||||
<Grid>
|
<Grid>
|
||||||
<!-- Color Picker for Color properties with colored background -->
|
<!-- Color Picker for Color properties -->
|
||||||
<Border Background="{Binding ColorValue, Converter={StaticResource ColorToBrushConverter}}"
|
|
||||||
IsVisible="{Binding PropertyType, Converter={StaticResource IsColorTypeConverter}}"
|
|
||||||
CornerRadius="4"
|
|
||||||
Padding="4">
|
|
||||||
<ColorPicker Color="{Binding ColorValue, Mode=TwoWay}"
|
<ColorPicker Color="{Binding ColorValue, Mode=TwoWay}"
|
||||||
|
IsVisible="{Binding PropertyType, Converter={StaticResource IsColorTypeConverter}}"
|
||||||
IsEnabled="{Binding !IsReadOnly}"
|
IsEnabled="{Binding !IsReadOnly}"
|
||||||
IsAlphaEnabled="True"
|
IsAlphaEnabled="True"
|
||||||
HorizontalAlignment="Stretch">
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Width="{Binding $parent[Grid].Bounds.Width}">
|
||||||
<ColorPicker.Styles>
|
<ColorPicker.Styles>
|
||||||
<Style Selector="ColorPicker">
|
<Style Selector="ColorPicker">
|
||||||
<Setter Property="MaxWidth" Value="{x:Static sys:Double.PositiveInfinity}" />
|
<Setter Property="MinWidth" Value="0" />
|
||||||
|
<Setter Property="MaxWidth" Value="999999" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="ColorPicker > :is(Control)">
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
</Style>
|
</Style>
|
||||||
</ColorPicker.Styles>
|
</ColorPicker.Styles>
|
||||||
</ColorPicker>
|
</ColorPicker>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- NumericUpDown for numeric properties -->
|
<!-- NumericUpDown for numeric properties -->
|
||||||
<NumericUpDown Value="{Binding NumericValue, Mode=TwoWay}"
|
<NumericUpDown Value="{Binding NumericValue, Mode=TwoWay}"
|
||||||
IsVisible="{Binding PropertyType, Converter={StaticResource IsNumericTypeConverter}}"
|
IsVisible="{Binding PropertyType, Converter={StaticResource IsNumericTypeConverter}}"
|
||||||
IsReadOnly="{Binding IsReadOnly}"
|
IsReadOnly="{Binding IsReadOnly}"
|
||||||
FormatString="{Binding PropertyType, Converter={StaticResource NumericFormatConverter}}"
|
FormatString="{Binding PropertyType, Converter={StaticResource NumericFormatConverter}}"
|
||||||
AllowSpin="True"
|
|
||||||
ShowButtonSpinner="True"
|
|
||||||
HorizontalAlignment="Stretch" />
|
HorizontalAlignment="Stretch" />
|
||||||
|
|
||||||
<!-- CheckBox for boolean properties -->
|
<!-- CheckBox for boolean properties -->
|
||||||
@@ -281,30 +295,30 @@
|
|||||||
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
|
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
|
||||||
BorderThickness="0,0,0,1">
|
BorderThickness="0,0,0,1">
|
||||||
<Grid>
|
<Grid>
|
||||||
<!-- ColorPicker for color properties with colored background -->
|
<!-- Color Picker for Color properties -->
|
||||||
<Border Background="{Binding ColorValue, Converter={StaticResource ColorToBrushConverter}}"
|
|
||||||
IsVisible="{Binding PropertyType, Converter={StaticResource IsColorTypeConverter}}"
|
|
||||||
CornerRadius="4"
|
|
||||||
Padding="4">
|
|
||||||
<ColorPicker Color="{Binding ColorValue, Mode=TwoWay}"
|
<ColorPicker Color="{Binding ColorValue, Mode=TwoWay}"
|
||||||
|
IsVisible="{Binding PropertyType, Converter={StaticResource IsColorTypeConverter}}"
|
||||||
IsEnabled="{Binding !IsReadOnly}"
|
IsEnabled="{Binding !IsReadOnly}"
|
||||||
HorizontalAlignment="Stretch">
|
IsAlphaEnabled="True"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Width="{Binding $parent[Grid].Bounds.Width}">
|
||||||
<ColorPicker.Styles>
|
<ColorPicker.Styles>
|
||||||
<Style Selector="ColorPicker">
|
<Style Selector="ColorPicker">
|
||||||
<Setter Property="Width" Value="{x:Static sys:Double.PositiveInfinity}" />
|
<Setter Property="MinWidth" Value="0" />
|
||||||
|
<Setter Property="MaxWidth" Value="999999" />
|
||||||
|
</Style>
|
||||||
|
<Style Selector="ColorPicker > :is(Control)">
|
||||||
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
</Style>
|
</Style>
|
||||||
</ColorPicker.Styles>
|
</ColorPicker.Styles>
|
||||||
</ColorPicker>
|
</ColorPicker>
|
||||||
</Border>
|
|
||||||
|
|
||||||
<!-- NumericUpDown for numeric properties -->
|
<!-- NumericUpDown for numeric properties -->
|
||||||
<NumericUpDown Value="{Binding NumericValue, Mode=TwoWay}"
|
<NumericUpDown Value="{Binding NumericValue, Mode=TwoWay}"
|
||||||
IsVisible="{Binding PropertyType, Converter={StaticResource IsNumericTypeConverter}}"
|
IsVisible="{Binding PropertyType, Converter={StaticResource IsNumericTypeConverter}}"
|
||||||
IsReadOnly="{Binding IsReadOnly}"
|
IsReadOnly="{Binding IsReadOnly}"
|
||||||
FormatString="{Binding PropertyType, Converter={StaticResource NumericFormatConverter}}"
|
FormatString="{Binding PropertyType, Converter={StaticResource NumericFormatConverter}}"
|
||||||
AllowSpin="True"
|
|
||||||
ShowButtonSpinner="True"
|
|
||||||
HorizontalAlignment="Stretch" />
|
HorizontalAlignment="Stretch" />
|
||||||
|
|
||||||
<!-- CheckBox for boolean properties -->
|
<!-- CheckBox for boolean properties -->
|
||||||
|
|||||||
@@ -288,11 +288,10 @@ public class PropertyGrid : TemplatedControl
|
|||||||
// Apply search filter
|
// Apply search filter
|
||||||
if (!string.IsNullOrWhiteSpace(_searchText))
|
if (!string.IsNullOrWhiteSpace(_searchText))
|
||||||
{
|
{
|
||||||
var searchLower = _searchText.ToLowerInvariant();
|
|
||||||
filtered = filtered.Where(p =>
|
filtered = filtered.Where(p =>
|
||||||
p.DisplayName.ToLowerInvariant().Contains(searchLower) ||
|
p.DisplayName.Contains(_searchText, StringComparison.OrdinalIgnoreCase) ||
|
||||||
(p.Category?.ToLowerInvariant().Contains(searchLower) ?? false) ||
|
(p.Category?.Contains(_searchText, StringComparison.OrdinalIgnoreCase) ?? false) ||
|
||||||
(p.Description?.ToLowerInvariant().Contains(searchLower) ?? false));
|
(p.Description?.Contains(_searchText, StringComparison.OrdinalIgnoreCase) ?? false));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Populate flat list
|
// Populate flat list
|
||||||
|
|||||||
@@ -8,8 +8,16 @@ namespace Avalonia.PropertyGrid.Controls;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an Avalonia.Media.Color to a SolidColorBrush
|
/// Converts an Avalonia.Media.Color to a SolidColorBrush
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ColorToBrushConverter : IValueConverter
|
public sealed class ColorToBrushConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a Color to a SolidColorBrush.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Color value to convert.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>A SolidColorBrush with the specified color.</returns>
|
||||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Color color)
|
if (value is Color color)
|
||||||
@@ -21,9 +29,17 @@ public class ColorToBrushConverter : IValueConverter
|
|||||||
return new SolidColorBrush(Colors.Transparent);
|
return new SolidColorBrush(Colors.Transparent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a SolidColorBrush back to a Color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The SolidColorBrush value to convert back.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>The Color from the brush.</returns>
|
||||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
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;
|
return brush.Color;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,16 @@ namespace Avalonia.PropertyGrid.Controls;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts boolean value to its negation for two-way binding
|
/// Converts boolean value to its negation for two-way binding
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NegateBoolConverter : IValueConverter
|
public sealed class NegateBoolConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a boolean value to its negation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The boolean value to convert.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>The negated boolean value.</returns>
|
||||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is bool boolValue)
|
if (value is bool boolValue)
|
||||||
@@ -18,6 +26,14 @@ public class NegateBoolConverter : IValueConverter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a boolean value back to its negation (two-way binding).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The boolean value to convert back.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>The negated boolean value.</returns>
|
||||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is bool boolValue)
|
if (value is bool boolValue)
|
||||||
|
|||||||
@@ -7,8 +7,16 @@ namespace Avalonia.PropertyGrid.Controls;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts PropertyType to appropriate numeric format string
|
/// Converts PropertyType to appropriate numeric format string
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class NumericFormatConverter : IValueConverter
|
public sealed class NumericFormatConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a Type to an appropriate numeric format string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to convert.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>A format string like "N2" for floating point or "N0" for integers.</returns>
|
||||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
@@ -26,6 +34,15 @@ public class NumericFormatConverter : IValueConverter
|
|||||||
return "N0";
|
return "N0";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The value to convert back.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>Throws NotImplementedException.</returns>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ namespace Avalonia.PropertyGrid.Controls;
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts indent level to left margin
|
/// Converts indent level to left margin
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IndentToMarginConverter : IValueConverter
|
public sealed class IndentToMarginConverter : IValueConverter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts indent level to left margin.
|
/// Converts indent level to left margin.
|
||||||
@@ -33,7 +33,7 @@ public class IndentToMarginConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts enum type to list of enum values
|
/// Converts enum type to list of enum values
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class EnumValuesConverter : IValueConverter
|
public sealed class EnumValuesConverter : IValueConverter
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an enum type to an array of its values.
|
/// Converts an enum type to an array of its values.
|
||||||
@@ -59,8 +59,16 @@ public class EnumValuesConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type is an enum
|
/// Checks if a type is an enum
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsEnumConverter : IValueConverter
|
public sealed class IsEnumConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the provided type is an enum.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to check.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>True if the type is an enum, otherwise false.</returns>
|
||||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
@@ -70,6 +78,10 @@ public class IsEnumConverter : IValueConverter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@@ -79,8 +91,16 @@ public class IsEnumConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type is a simple type (string, number, bool, etc.)
|
/// Checks if a type is a simple type (string, number, bool, etc.)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsSimpleTypeConverter : IValueConverter
|
public sealed class IsSimpleTypeConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the provided type is a simple type like string, number, DateTime, etc.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to check.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>True if the type is a simple type, otherwise false.</returns>
|
||||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
@@ -96,6 +116,10 @@ public class IsSimpleTypeConverter : IValueConverter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@@ -105,8 +129,16 @@ public class IsSimpleTypeConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type matches the specified type name
|
/// Checks if a type matches the specified type name
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TypeToBoolConverter : IValueConverter
|
public sealed class TypeToBoolConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the type's name matches the specified parameter string.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to check.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">The type name to match against.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>True if the type name matches, otherwise false.</returns>
|
||||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type && parameter is string typeName)
|
if (value is Type type && parameter is string typeName)
|
||||||
@@ -116,6 +148,10 @@ public class TypeToBoolConverter : IValueConverter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@@ -125,8 +161,16 @@ public class TypeToBoolConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts Color to/from hex string representation
|
/// Converts Color to/from hex string representation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ColorToStringConverter : IValueConverter
|
public sealed class ColorToStringConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a Color to a hex string representation.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Color to convert.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>A hex string representation of the color (e.g., "#AARRGGBB").</returns>
|
||||||
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Media.Color color)
|
if (value is Media.Color color)
|
||||||
@@ -136,6 +180,14 @@ public class ColorToStringConverter : IValueConverter
|
|||||||
return value?.ToString();
|
return value?.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Converts a hex string back to a Color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The hex string to convert.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>The parsed Color, or Black if parsing fails.</returns>
|
||||||
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is string hexString && !string.IsNullOrWhiteSpace(hexString))
|
if (value is string hexString && !string.IsNullOrWhiteSpace(hexString))
|
||||||
@@ -143,7 +195,7 @@ public class ColorToStringConverter : IValueConverter
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
hexString = hexString.Trim();
|
hexString = hexString.Trim();
|
||||||
if (!hexString.StartsWith("#"))
|
if (!hexString.StartsWith('#'))
|
||||||
hexString = "#" + hexString;
|
hexString = "#" + hexString;
|
||||||
|
|
||||||
return Media.Color.Parse(hexString);
|
return Media.Color.Parse(hexString);
|
||||||
@@ -161,8 +213,16 @@ public class ColorToStringConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type is Color
|
/// Checks if a type is Color
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsColorTypeConverter : IValueConverter
|
public sealed class IsColorTypeConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the provided type is Avalonia.Media.Color.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to check.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional "Invert" parameter to invert the result.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>True if the type is Color (or inverted if parameter is "Invert"), otherwise false.</returns>
|
||||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
@@ -187,6 +247,10 @@ public class IsColorTypeConverter : IValueConverter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@@ -196,8 +260,16 @@ public class IsColorTypeConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type is numeric
|
/// Checks if a type is numeric
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsNumericTypeConverter : IValueConverter
|
public sealed class IsNumericTypeConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the provided type is a numeric type (int, long, float, double, decimal, etc.).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to check.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional "Invert" parameter to invert the result.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>True if the type is numeric (or inverted if parameter is "Invert"), otherwise false.</returns>
|
||||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
@@ -225,6 +297,10 @@ public class IsNumericTypeConverter : IValueConverter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@@ -234,8 +310,16 @@ public class IsNumericTypeConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type is neither Color nor Numeric nor Boolean nor Enum (for fallback TextBox)
|
/// Checks if a type is neither Color nor Numeric nor Boolean nor Enum (for fallback TextBox)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsOtherTypeConverter : IValueConverter
|
public sealed class IsOtherTypeConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the type is not Color, Numeric, Boolean, or Enum (used for fallback TextBox editor).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to check.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional parameter.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>True if the type is not a special type, otherwise false.</returns>
|
||||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
@@ -255,6 +339,10 @@ public class IsOtherTypeConverter : IValueConverter
|
|||||||
return true; // Default to showing TextBox
|
return true; // Default to showing TextBox
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
@@ -264,8 +352,16 @@ public class IsOtherTypeConverter : IValueConverter
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Checks if a type is boolean
|
/// Checks if a type is boolean
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class IsBooleanTypeConverter : IValueConverter
|
public sealed class IsBooleanTypeConverter : IValueConverter
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Checks if the provided type is boolean.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The Type to check.</param>
|
||||||
|
/// <param name="targetType">The target type.</param>
|
||||||
|
/// <param name="parameter">Optional "Invert" parameter to invert the result.</param>
|
||||||
|
/// <param name="culture">Culture information.</param>
|
||||||
|
/// <returns>True if the type is boolean (or inverted if parameter is "Invert"), otherwise false.</returns>
|
||||||
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
if (value is Type type)
|
if (value is Type type)
|
||||||
@@ -290,6 +386,10 @@ public class IsBooleanTypeConverter : IValueConverter
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Not supported for this converter.
|
||||||
|
/// </summary>
|
||||||
|
/// <exception cref="NotImplementedException">This converter does not support ConvertBack.</exception>
|
||||||
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ public class DateTimeEditor : PropertyEditor
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converter for DateTime to DateTimeOffset
|
/// Converter for DateTime to DateTimeOffset
|
||||||
/// </summary>
|
/// </summary>
|
||||||
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)
|
public object? Convert(object? value, Type targetType, object? parameter, System.Globalization.CultureInfo culture)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -47,6 +47,10 @@ public class CategoryGroup : INotifyPropertyChanged
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public int PropertyCount => Properties.Count;
|
public int PropertyCount => Properties.Count;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Raises the PropertyChanged event for the specified property.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyName">The name of the property that changed.</param>
|
||||||
protected virtual void OnPropertyChanged(string propertyName)
|
protected virtual void OnPropertyChanged(string propertyName)
|
||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ public class PropertyItem : INotifyPropertyChanged
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
var hexString = value?.Trim() ?? "";
|
var hexString = value?.Trim() ?? "";
|
||||||
if (!hexString.StartsWith("#"))
|
if (!hexString.StartsWith('#'))
|
||||||
hexString = "#" + hexString;
|
hexString = "#" + hexString;
|
||||||
|
|
||||||
Value = Media.Color.Parse(hexString);
|
Value = Media.Color.Parse(hexString);
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ public class NetworkSettings : INotifyPropertyChanged
|
|||||||
{
|
{
|
||||||
private string _hostname = "api.example.com";
|
private string _hostname = "api.example.com";
|
||||||
private int _port = 443;
|
private int _port = 443;
|
||||||
private bool _useProxy = false;
|
private bool _useProxy;
|
||||||
private string _proxyAddress = string.Empty;
|
private string _proxyAddress = string.Empty;
|
||||||
|
|
||||||
[Display(Name = "Hostname", Description = "Server hostname or IP address")]
|
[Display(Name = "Hostname", Description = "Server hostname or IP address")]
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using System;
|
|||||||
|
|
||||||
namespace AdvancedExample;
|
namespace AdvancedExample;
|
||||||
|
|
||||||
class Program
|
sealed class Program
|
||||||
{
|
{
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ using Avalonia;
|
|||||||
|
|
||||||
namespace QuickStartExample;
|
namespace QuickStartExample;
|
||||||
|
|
||||||
class Program
|
sealed class Program
|
||||||
{
|
{
|
||||||
[STAThread]
|
[STAThread]
|
||||||
public static void Main(string[] args) => BuildAvaloniaApp()
|
public static void Main(string[] args) => BuildAvaloniaApp()
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<Solution>
|
||||||
|
<Folder Name="/Examples/">
|
||||||
|
<Project Path="Examples/AdvancedExample/AdvancedExample.csproj" />
|
||||||
|
<Project Path="Examples/QuickStartExample/QuickStartExample.csproj" />
|
||||||
|
</Folder>
|
||||||
|
<Project Path="Avalonia.PropertyGrid/Avalonia.PropertyGrid.csproj" />
|
||||||
|
</Solution>
|
||||||
Reference in New Issue
Block a user