Files
Matthias Heil 37720f103b 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.
2026-08-13 09:49:27 +02:00

379 lines
31 KiB
XML

<Styles xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Avalonia.PropertyGrid.Controls"
xmlns:models="using:Avalonia.PropertyGrid.Models"
xmlns:sys="clr-namespace:System;assembly=System.Runtime">
<Design.PreviewWith>
<Border Padding="20" Width="400" Height="600">
<controls:PropertyGrid />
</Border>
</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">
<Setter Property="Background" Value="{DynamicResource SystemControlBackgroundAltHighBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource SystemControlForegroundBaseMediumLowBrush}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="Template">
<ControlTemplate>
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="4">
<Grid RowDefinitions="Auto,*">
<!-- Search/Filter Box -->
<Border Grid.Row="0"
Padding="8"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="0,0,0,1">
<StackPanel>
<TextBox Name="PART_SearchBox"
PlaceholderText="Search properties..."
Text="{Binding $parent[controls:PropertyGrid].SearchText, Mode=TwoWay}" />
<!-- Debug: Show count -->
<TextBlock Text="{Binding $parent[controls:PropertyGrid].FilteredProperties.Count, StringFormat='Properties: {0}'}"
FontSize="10"
Foreground="Gray"
Margin="0,4,0,0" />
</StackPanel>
</Border>
<!-- Properties List -->
<ScrollViewer Grid.Row="1"
HorizontalScrollBarVisibility="Disabled"
VerticalScrollBarVisibility="Auto">
<Panel>
<!-- Category View -->
<ItemsControl Name="PART_CategoryItemsControl"
ItemsSource="{TemplateBinding CategoryGroups}"
IsVisible="{TemplateBinding ShowCategories}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="models:CategoryGroup">
<StackPanel>
<!-- Category Header -->
<Border Background="{DynamicResource SystemControlHighlightAccentBrush}"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="0,0,0,1"
Padding="8,4"
HorizontalAlignment="Left">
<StackPanel Orientation="Horizontal" Spacing="4">
<!-- Expand/Collapse Toggle -->
<ToggleButton IsChecked="{Binding IsExpanded, Mode=TwoWay}"
Width="16" Height="16"
Padding="0"
VerticalAlignment="Center">
<Panel>
<!-- Right Arrow (collapsed/closed state) -->
<Path IsVisible="{Binding !IsExpanded}"
Data="M 4,2 L 10,8 L 4,14 Z"
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
Width="12" Height="12"
Stretch="Uniform" />
<!-- Down Arrow (expanded/open state) -->
<Path IsVisible="{Binding IsExpanded}"
Data="M 2,4 L 8,10 L 14,4 Z"
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
Width="12" Height="12"
Stretch="Uniform" />
</Panel>
</ToggleButton>
<!-- Category Name -->
<TextBlock Text="{Binding CategoryName}"
FontWeight="Bold"
Foreground="White"
VerticalAlignment="Center" />
<!-- Property Count -->
<TextBlock Text="{Binding PropertyCount, StringFormat='({0})'}"
FontSize="11"
Foreground="White"
Opacity="0.8"
VerticalAlignment="Center"
Margin="4,0,0,0" />
</StackPanel>
</Border>
<!-- Properties in Category -->
<ItemsControl ItemsSource="{Binding Properties}"
IsVisible="{Binding IsExpanded}"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="models:PropertyItem">
<Border Margin="16,0,0,0" BorderThickness="0">
<Grid MinHeight="32"
Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="150" MaxWidth="400" SharedSizeGroup="PropertyName" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<!-- Property Name -->
<Border Grid.Column="0"
Padding="8,4"
Margin="{Binding IndentLevel, Converter={StaticResource IndentConverter}}"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="0,0,1,1">
<StackPanel Orientation="Horizontal" Spacing="4">
<!-- Expander for complex types with arrow icons -->
<ToggleButton IsVisible="{Binding IsExpandable}"
IsChecked="{Binding IsExpanded}"
Width="16" Height="16"
Padding="0"
VerticalAlignment="Center">
<Panel >
<!-- Right Arrow (collapsed/closed state) -->
<Path IsVisible="{Binding !IsExpanded}"
Data="M 4,2 L 10,8 L 4,14 Z"
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
Width="12" Height="12"
Stretch="Uniform" />
<!-- Down Arrow (expanded/open state) -->
<Path IsVisible="{Binding IsExpanded}"
Data="M 2,4 L 8,10 L 14,4 Z"
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
Width="12" Height="12"
Stretch="Uniform" />
</Panel>
</ToggleButton>
<TextBlock Text="{Binding DisplayName}"
VerticalAlignment="Center"
ToolTip.Tip="{Binding Description}" />
</StackPanel>
</Border>
<!-- Splitter -->
<GridSplitter Grid.Column="1"
Width="4"
Background="Transparent"
ResizeDirection="Columns" />
<!-- Property Value Editor -->
<Border Grid.Column="2"
Padding="4"
Background="{DynamicResource SystemControlBackgroundChromeMediumLowBrush}"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="0,0,0,1">
<Grid>
<!-- Color Picker for Color properties -->
<ColorPicker Color="{Binding ColorValue, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsColorTypeConverter}}"
IsEnabled="{Binding !IsReadOnly}"
IsAlphaEnabled="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Width="{Binding $parent[Grid].Bounds.Width}">
<ColorPicker.Styles>
<Style Selector="ColorPicker">
<Setter Property="MinWidth" Value="0" />
<Setter Property="MaxWidth" Value="999999" />
</Style>
<Style Selector="ColorPicker > :is(Control)">
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</ColorPicker.Styles>
</ColorPicker>
<!-- NumericUpDown for numeric properties -->
<NumericUpDown Value="{Binding NumericValue, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsNumericTypeConverter}}"
IsReadOnly="{Binding IsReadOnly}"
FormatString="{Binding PropertyType, Converter={StaticResource NumericFormatConverter}}"
HorizontalAlignment="Stretch" />
<!-- CheckBox for boolean properties -->
<CheckBox IsChecked="{Binding BooleanValue, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsBooleanTypeConverter}}"
IsEnabled="{Binding !IsReadOnly}"
Content="{Binding DisplayName}"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<!-- ComboBox for enum properties -->
<ComboBox SelectedItem="{Binding Value, Mode=TwoWay}"
ItemsSource="{Binding PropertyType, Converter={StaticResource EnumValuesConverter}}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsEnumConverter}}"
IsEnabled="{Binding !IsReadOnly}"
HorizontalAlignment="Stretch" />
<!-- TextBox for other properties -->
<TextBox Text="{Binding ValueString, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsOtherTypeConverter}}"
IsReadOnly="{Binding IsReadOnly}"
HorizontalAlignment="Stretch" />
</Grid>
</Border>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!-- Flat List View -->
<ItemsControl Name="PART_ItemsControl"
ItemsSource="{TemplateBinding FilteredProperties}"
IsVisible="{TemplateBinding ShowCategories, Converter={StaticResource NegateBoolConverter}}"
Grid.IsSharedSizeScope="True">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="models:PropertyItem">
<Border Margin="0,0,0,0" BorderThickness="0">
<Grid MinHeight="32"
Background="Transparent">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="150" MaxWidth="400" SharedSizeGroup="PropertyName" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<!-- Property Name -->
<Border Grid.Column="0"
Padding="8,4"
Margin="{Binding IndentLevel, Converter={StaticResource IndentConverter}}"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="0,0,1,1">
<StackPanel Orientation="Horizontal" Spacing="4">
<!-- Expander for complex types with arrow icons -->
<ToggleButton IsVisible="{Binding IsExpandable}"
IsChecked="{Binding IsExpanded}"
Width="16" Height="16"
Padding="0"
VerticalAlignment="Center">
<Panel>
<!-- Right Arrow (collapsed/closed state) -->
<Path IsVisible="{Binding !IsExpanded}"
Data="M 4,2 L 10,8 L 4,14 Z"
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
Width="12" Height="12"
Stretch="Uniform" />
<!-- Down Arrow (expanded/open state) -->
<Path IsVisible="{Binding IsExpanded}"
Data="M 2,4 L 8,10 L 14,4 Z"
Fill="{DynamicResource SystemControlForegroundBaseHighBrush}"
Width="12" Height="12"
Stretch="Uniform" />
</Panel>
</ToggleButton>
<TextBlock Text="{Binding DisplayName}"
VerticalAlignment="Center"/>
</StackPanel>
</Border>
<!-- Splitter -->
<GridSplitter Grid.Column="1"
Width="4"
Background="Transparent"
ResizeDirection="Columns" />
<!-- Property Value -->
<Border Grid.Column="2"
Padding="8,4"
Background="{DynamicResource SystemControlBackgroundAltHighBrush}"
BorderBrush="{DynamicResource SystemControlForegroundBaseMediumLowBrush}"
BorderThickness="0,0,0,1">
<Grid>
<!-- Color Picker for Color properties -->
<ColorPicker Color="{Binding ColorValue, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsColorTypeConverter}}"
IsEnabled="{Binding !IsReadOnly}"
IsAlphaEnabled="True"
HorizontalAlignment="Stretch"
VerticalAlignment="Center"
Width="{Binding $parent[Grid].Bounds.Width}">
<ColorPicker.Styles>
<Style Selector="ColorPicker">
<Setter Property="MinWidth" Value="0" />
<Setter Property="MaxWidth" Value="999999" />
</Style>
<Style Selector="ColorPicker > :is(Control)">
<Setter Property="HorizontalAlignment" Value="Stretch" />
</Style>
</ColorPicker.Styles>
</ColorPicker>
<!-- NumericUpDown for numeric properties -->
<NumericUpDown Value="{Binding NumericValue, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsNumericTypeConverter}}"
IsReadOnly="{Binding IsReadOnly}"
FormatString="{Binding PropertyType, Converter={StaticResource NumericFormatConverter}}"
HorizontalAlignment="Stretch" />
<!-- CheckBox for boolean properties -->
<CheckBox IsChecked="{Binding BooleanValue, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsBooleanTypeConverter}}"
IsEnabled="{Binding !IsReadOnly}"
Content="{Binding DisplayName}"
VerticalAlignment="Center"
HorizontalAlignment="Left" />
<!-- ComboBox for enum properties -->
<ComboBox SelectedItem="{Binding Value, Mode=TwoWay}"
ItemsSource="{Binding PropertyType, Converter={StaticResource EnumValuesConverter}}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsEnumConverter}}"
IsEnabled="{Binding !IsReadOnly}"
HorizontalAlignment="Stretch" />
<!-- TextBox for other properties -->
<TextBox Text="{Binding ValueString, Mode=TwoWay}"
IsVisible="{Binding PropertyType, Converter={StaticResource IsOtherTypeConverter}}"
IsReadOnly="{Binding IsReadOnly}"
HorizontalAlignment="Stretch" />
</Grid>
</Border>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Panel>
</ScrollViewer>
</Grid>
</Border>
</ControlTemplate>
</Setter>
</Style>
<!-- Converters and Resources -->
<Style Selector="controls|PropertyGrid">
<Style.Resources>
<controls:IndentToMarginConverter x:Key="IndentConverter" />
<controls:EnumValuesConverter x:Key="EnumValuesConverter" />
<controls:IsEnumConverter x:Key="IsEnumConverter" />
<controls:IsSimpleTypeConverter x:Key="IsSimpleTypeConverter" />
<controls:TypeToBoolConverter x:Key="TypeToBoolConverter" />
<controls:ColorToStringConverter x:Key="ColorToStringConverter" />
<controls:ColorToBrushConverter x:Key="ColorToBrushConverter" />
<controls:IsColorTypeConverter x:Key="IsColorTypeConverter" />
<controls:IsNumericTypeConverter x:Key="IsNumericTypeConverter" />
<controls:IsBooleanTypeConverter x:Key="IsBooleanTypeConverter" />
<controls:IsOtherTypeConverter x:Key="IsOtherTypeConverter" />
<controls:NumericFormatConverter x:Key="NumericFormatConverter" />
<controls:NegateBoolConverter x:Key="NegateBoolConverter" />
</Style.Resources>
</Style>
</Styles>